You are here

Extending PortableApps.comLauncher

15 posts / 0 new
Last post
demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
Extending PortableApps.comLauncher

I've got some ideas on extending PortableApps.comLauncher. I was just wondering how I go about getting my ideas out.

One of my ideas is something like:

In the PortableApps.comLauncher.nsi file:

;=# Define where the custom.nsh file is.
!define NSH	`${PACKAGE}\App\AppInfo\Launcher\custom.nsh`

;=# Defines the RequestLevel for use with the manifest
; See http://softables.tk/docs/advanced/uac#manifests
!searchparse /noerrors /file `${NSH}` `;!define RequestLevel ` RequestLevel ``
!if ${RequestLevel} == USER
	!define /redef RequestLevel USER
!else if ${RequestLevel} == ADMIN
	!define /redef RequestLevel ADMIN
!else 
	!define /redef RequestLevel USER
!endif

In the custom.nsh file:
;!define RequestLevel USER
or
;!define RequestLevel ADMIN

Now this is just one of the ideas I have. I feel like it would be advantageous on your guys part if we tried to implement some of these ideas within PAL.

demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
Need more convincing?

Okay... How about this one? I'm not sure where you guys are on the dotNET feature but here's a function which could help. As it is written right now it only checks for 4.5 to 4.7..

Function dotNETCheck
	!define CheckDOTNET "!insertmacro _CheckDOTNET"
	!macro _CheckDOTNET _RESULT _VALUE
		Push `${_VALUE}`
		Call dotNETCheck
		Pop ${_RESULT}
	!macroend
	Exch $1
	Push $0
	Push $1
	
	${If} $1 == "4.7"
		StrCpy $R1 460798
	${ElseIf} $1 == "4.6.2"
		StrCpy $R1 394802
	${ElseIf} $1 == "4.6.1"
		StrCpy $R1 394254
	${ElseIf} $1 == "4.6"
		StrCpy $R1 393295
	${ElseIf} $1 == "4.5.2"
		StrCpy $R1 379893
	${ElseIf} $1 == "4.5.1"
		StrCpy $R1 378675
	${ElseIf} $1 == "4.5"
		StrCpy $R1 378389
	${Else}
		Goto dotNET_FALSE
	${EndIf}
	
	ReadRegDWORD $R0 HKLM `SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full` `Release`
	IfErrors dotNET_FALSE
	
	IntCmp $R0 $R1 dotNET_TRUE dotNET_FALSE
	
	dotNET_TRUE:
	StrCpy $0 true
	Goto dotNET_END
	
	dotNET_FALSE:
	StrCpy $0 false
	SetErrors
	
	dotNET_END:	
	Pop $1
	Exch $0
FunctionEnd

In the PortableApps.comLauncher.nsi file:

ClearErrors
!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `UsesDotNetVersion=` dotNET_Version ``
!ifdef dotNET_Version
	!if ! ${dotNET_Version} == ""
		${CheckDOTNET} $0 "${dotNET_Version}"
		IfErrors 0 +4
		MessageBox MB_ICONSTOP|MB_TOPMOST \
		`You must have v${dotNET_Version} or greater of the .NET Framework installed. Launcher aborting!`
		Call Unload
		Quit
		StrCmpS $0 true 0 -3
	!else
		!error "The key 'UsesDotNetVersion' in AppInfo.ini is set but has no value!\$r\$n"
		!error "If this PAF does not require the .NET Framework please omit this key entirely."
	!endif
!endif

Okay, so first this snippet of code will check the AppInfo.ini file for a key (UsesDotNetVersion) for it's value which should be the required version number. If the key exists it will set a !define (${dotNET_Version}) to whatever the key's value is. Afterwhich it'll call the function to check the host PC to see if .NET is even installed and if so what version the PC is compatible with. The function uses IntCmp to see if ${dotNET_Version} and the value found in the registry are a match. $0 will hold true if the host PC meets the requirements otherwise $0 will be set to false and an error flag is set which is checked for. If any errors occur when launching the portable application it will alert the users of the required .NET version the system needs, calls Unload and quits. If when compiling the portable application and the compiler finds the key UsesDotNetVersion and it's empty, the compiler will stop immediately with an error message saying if the PAF does not require the .NET Framework to omit the key entirely.

daemon.devin

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 3 weeks 32 min ago
DeveloperModerator
Joined: 2008-07-24 18:46
See upcoming code

For DotNet support, I refer you to the existing planned support: https://sourceforge.net/p/portableapps/launcher/ci/default/tree/Other/So...

(Note to self, I need to pull this into the github repo)

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 3 weeks 32 min ago
DeveloperModerator
Joined: 2008-07-24 18:46
Already set?

Is this not already set when using RunAsAdmin?

demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
You correct but....

That was just an example.. more of a concept really.

Allow me to elaborate further. For instance, let's act like registering DLLs or Services were supported in PAL. Using the above concept we could simply write the following in custom.nsh;!define REGISTERDLL true and/or ;!define SERVICES true;let's go ahead and do ;!define REGISTRY true as well. This would be written in the custom.nsh file and commented out so it's not executed in the launcher.

I hope you're still following me. Now inside the PortableApps.comLauncher.nsi file you could have something similar to this:

;=# Define where the custom.nsh file is.
!define NSH	`${PACKAGE}\App\AppInfo\Launcher\custom.nsh`

!searchparse /noerrors /file `${NSH}` `;!define REGISTRY ` REGISTRY ``
!searchparse /noerrors /file `${NSH}` `;!define REGISTERDLL ` REGISTERDLL ``
!searchparse /noerrors /file `${NSH}` `;!define SERVICES ` SERVICES ``

!if ${REGISTRY} == true
	!define /redef REGISTRY ;=== enable for registry
!else
	!ifdef REGISTRY
		!undef REGISTRY
	!endif
!endif
!if ${REGISTERDLL} == true
	!define /redef REGISTERDLL ;=== enable for registering DLLs macros
!else
	!ifdef REGISTERDLL
		!undef REGISTERDLL
	!endif
!endif
!if ${SERVICES} == true
	!define /redef SERVICES ;=== enable for services
!else
	!ifdef SERVICES
		!undef SERVICES
	!endif
!endif

;= Random code...

Function Pre
	;= Random code...
	${If} $SecondaryLaunch != true
		!ifdef SERVICES
			${RunSegment} Services
		!endif
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
	${EndIf}
	!ifdef REGISTRY
		${RunSegment} Registry ;= Why not do this for Registry support as well?
	!endif
	${RunSegment} Custom
	${RunSegment} RunLocally
	;= Random code...
FunctionEnd
Function PrePrimary
	;= Random code...
	${RunSegment} FilesMove
	${RunSegment} DirectoriesMove
	!ifdef REGISTRY
		${RunSegment} RegistryKeys
		${RunSegment} RegistryValueBackupDelete
	!endif
	${If} $SecondaryLaunch != true
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
	${EndIf}
	!ifdef REGISTRY
		${RunSegment} RegistryValueWrite ;= this should be here after Registering DLLs.
	!endif
	${If} $SecondaryLaunch != true
		!ifdef SERVICES
			${RunSegment} Services
		!endif
	${EndIf}
	;= Random code...
FunctionEnd

Anyway, I'm sure you can see the gist of what I'm getting at. Basically, by doing something similar as above you could reduce the workload and bloat when the compiled PAF is launched. This will mean that the code is only included/compiled if the specific !define is set. This will decrease the installer overhead in theory, but in practice there is little change I believe (I have no evidence to support this though ..lol.). Blum

daemon.devin

John T. Haller
John T. Haller's picture
Online
Last seen: 18 min 4 sec ago
AdminDeveloperModeratorTranslator
Joined: 2005-11-28 22:21
Not Following

I'm not following what you're trying to accomplish with this. These things are defined in the PAL ini and then handled in PAL itself. We won't be basing usage on defines within custom.nsh at all. We'll be adding features to PAL to discourage custom.nsh usage eventually.

Sometimes, the impossible can become possible, if you're awesome!

demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
Okay.. then forget the custom

Okay.. then forget the custom.nsh file. It's not necessary to use this with custom.nsh anyway. I was just brain-storming. You could just use the Launcher.ini for the code above. Instead of using:

!searchparse /noerrors /file `${NSH}` `;!define SERVICES ` SERVICES ``
!if ${SERVICES} == true
	!define /redef SERVICES ;=== enable for services
!else
	!ifdef SERVICES
		!undef SERVICES
	!endif
!endif

You could use the AppInfo.ini with a new section; something like [Dependencies]Services=true and/or [Dependencies]RegisterDLLs=true. So you'd instead have this in PortableApps.comLauncher.nsi:

!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `Services=` SERVICES``
!if ${SERVICES} == true
	!define /redef SERVICES ;=== enable for services
!else
	!ifdef SERVICES
		!undef SERVICES
	!endif
!endif

You really don't see the potential here? It think it's a brilliant on/off switch mechanism. Even more so you could drop the command line call within GeneratorWizard.nsi and use this concept instead like the following:

!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `AppID=` APPNAME ``
!searchreplace APP "${APPNAME}" "Portable" ""
!searchreplace APP64 "${APPNAME}" "Portable" "64"
!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `Name=` PORTABLEAPPNAME ``
!searchreplace FULLNAME "${PORTABLEAPPNAME}" " Portable" ""
!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `Trademarks=` TRADEMARK ``
!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `Publisher=` PUBLISHER ``
!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `PackageVersion=` PACKAGE_VERSION ``
!searchparse /noerrors /file ${PACKAGE}\App\AppInfo\appinfo.ini `Start=` OUTFILE ``

Name		`${PORTABLEAPPNAME}`
OutFile		`${PACKAGE}\${APPNAME}.exe`
Icon		`${PACKAGE}\App\AppInfo\appicon.ico`
Caption		`${FULLNAME}`

!define /date YEAR		`%Y`

!ifdef PACKAGE_VERSION
	!if ! ${PACKAGE_VERSION} == ""
		VIProductVersion	${PACKAGE_VERSION}
		VIAddVersionKey /LANG=${LANG_ENGLISH} FileVersion      ${PACKAGE_VERSION}
	!else
		!error "The key 'PackageVersion' in AppInfo.ini needs a value! (i.e. 0.0.0.0)"
	!endif
!else
	!error "The key 'PackageVersion' in AppInfo.ini is missing!"
!endif
!ifdef PUBLISHER
	!if ! "${PUBLISHER}" == ""
		VIAddVersionKey /LANG=${LANG_ENGLISH} CompanyName      `${PUBLISHER}`
		VIAddVersionKey /LANG=${LANG_ENGLISH} LegalCopyright   `Copyright © ${PUBLISHER} ${YEAR}`
	!else
		!error "The key 'Publisher' in AppInfo.ini needs a value!"
	!endif
!else
	!error "The key 'Publisher' in AppInfo.ini is missing!"
!endif
!ifdef APPNAME
	!if ! "${APPNAME}" == ""
		VIAddVersionKey /LANG=${LANG_ENGLISH} InternalName     `${APPNAME}Portable.exe`
		VIAddVersionKey /LANG=${LANG_ENGLISH} OriginalFilename `${APPNAME}.exe`
	!else
		!error "The key 'AppID' in AppInfo.ini needs a value!"
	!endif
!else
	!error "The key 'AppID' in AppInfo.ini is missing!"
!endif
!ifdef FULLNAME
	!if ! "${FULLNAME}" == ""
		VIAddVersionKey /LANG=${LANG_ENGLISH} ProductName      `${FULLNAME}`
		VIAddVersionKey /LANG=${LANG_ENGLISH} FileDescription  `${FULLNAME}`
	!else
		!error "The key 'Name' in AppInfo.ini needs a value!"
	!endif
!else
	!error "The key 'Name' in AppInfo.ini is missing!"
!endif
!ifdef TRADEMARK
	!if ! "${TRADEMARK}" == ""
		VIAddVersionKey /LANG=${LANG_ENGLISH} LegalTrademarks  `${TRADEMARK}`
	!else
		!ifdef TRADEMARK
			!undef TRADEMARK
		!endif
	!endif
!endif
VIAddVersionKey /LANG=${LANG_ENGLISH} Comments         `Developed by PortableApps.com`
VIAddVersionKey /LANG=${LANG_ENGLISH} ProductVersion   Portable

How about automatic code signing? (Needs NSIS3 because of !finalize)

${!echo}	`Gathering the certificate and other information then signing ${OUTFILE}...`

;=== Signing Macro
!define Finalize::Sign  `!insertmacro _Finalize::Sign`
!macro _Finalize::Sign _CMD
	!finalize `${_CMD}`
!macroend

;=== Certificate Defines
!define CERT		`PortableApps.com.p12`
!define SIGNTOOL	`"signtool.exe" sign /f "${CERT}" /p "" /t "http://timestamp.comodoca.com" /v "${PACKAGE}\${OUTFILE}"`

;=== Sign
${Finalize::Sign} `${SIGNTOOL}`

daemon.devin

demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
I responded to the issues

I responded to the issues posted on the PA.c Launcher's GitHub repo page (https://github.com/PortableApps/Launcher/issues).
I suggested a means for handling/checking .NET 4.5 and above as well as 4.0 and below. (I've outlined two possible usages for the `DotNet` segment)
I also suggested a means to help with the Windows Shutdown issue. It's not a full solution, but it is a start towards something.

daemon.devin

JLim
Offline
Last seen: 5 months 3 weeks ago
Joined: 2013-07-17 01:30
dot net checking

@Gord Caswell
dot net checking I suggest change to DotNetChecker plug-in (http://nsis.sourceforge.net/DotNetChecker_plug-in) and (https://github.com/ReVolly/NsisDotNetChecker) which currently can check upto 4.6.2 and is currently actively develope.

demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
The function I shared has a

The function I shared has a means to check for 4.5 all the way to present times and can easily be extended to support any future versions within a mere 10 seconds. It is also the recommended means of checking for 4.5 and later by Microsoft themselves (refer to this article for more information). Not to mention it doesn't depend on using a pointless DLL plugin which is probably using the same method I used in my function within it's source code anyway.

daemon.devin

3D1T0R
3D1T0R's picture
Offline
Last seen: 3 years 3 months ago
Developer
Joined: 2006-12-29 23:48
Actively developed?

I checked it out, and it doesn't look like the current maintainer has touched it in a while, despite there being good Pull Requests that fix major issues with it, so I'm not sure it can really be said to be "actively developed" at the moment.

~3D1T0R

JLim
Offline
Last seen: 5 months 3 weeks ago
Joined: 2013-07-17 01:30
May be the words I used are

May be the words I used are not correct. But this one is much newer than the one Gord Caswell used.

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 3 weeks 32 min ago
DeveloperModerator
Joined: 2008-07-24 18:46
Thanks for the feedback

Thanks for the feedback, guys. I'm not in front of my computer for the next couple days, but will respond fully to comments here and/or on GitHub at that time.

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 3 weeks 32 min ago
DeveloperModerator
Joined: 2008-07-24 18:46
Exploring

I'm exploring using defines in PortableApps.comLauncher.nsi to speed up compilation time, but not to give users any custom control, nor to add any extra features to launcher.ini.

demon.devin
demon.devin's picture
Offline
Last seen: 4 years 2 months ago
Developer
Joined: 2007-08-02 09:04
Good for you.

I can tell you that using defines for certain things is beneficial. I've accomplished a lot of really cool things with amazing results.

Good luck to with your development.

daemon.devin

Log in or register to post comments