You are here

Include FullAppDir as a variable in PAL?

18 posts / 0 new
Last post
Gord Caswell
Gord Caswell's picture
Offline
Last seen: 1 week 1 day ago
DeveloperModerator
Joined: 2008-07-24 18:46
Include FullAppDir as a variable in PAL?

All,

While removing the $Bits variable setting code from Custom.nsh files, I discovered that the only remaining portion of Custom.nsh for many apps is the chunk setting %FullAppDir%.

I'm thinking of adding $FullAppDir by default, using ${AppName}64 and ${AppName} as the directory names referenced.

The normal use appears to be AppName64 and AppName, with two apps using AppNamex64 and AppName, and two others using AppName\x64 and AppName\x86.
Moving forward, I recommend we standardize directory names as per the first option.

This would remove the need for Custom.nsh from:

  • AkelPad Portable
  • Daphne Portable
  • RapidCRC Portable
  • VirtualDub Portable
  • WaveShop Portable
  • WinMTR Portable

Additionally, it would leave only custom code for the following apps, rather than this relatively common code:

  • 7-Zip Portable
  • Avidemux Portable
  • Blender Portable
  • Krita Portable
  • TEncoder Portable
  • RawTherapee Portable
  • UltraDefrag Portable

This would cover all official applications using FullAppDir, with the exception of Listary.

Thoughts?

demon.devin
demon.devin's picture
Offline
Last seen: 2 years 1 month ago
Developer
Joined: 2007-08-02 09:04
Well, you're trying to

Well, you're trying to eliminate the need for the custom.nsh file so I would say move forward. If I'm understanding you correctly, the first method is what I did within my code.

daemon.devin

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
Wouldn't AppName$Bits be better?

I was under the impression that the 32-bit and 64-bit app directories were generally named after the way the publisher of the base app distributes official releases, so as to make repackaging easier for the developer(s) involved. If this is going to change, then I think a better way to standardize the hybrid IA32/AMD64 apps' FullAppDir would be to use the AppName$Bits format, making the 32 & 64 bit variants be "AppName32" and "AppName64" respectively. However, I'm not sure this is the best way to go about it.

I would like to propose that instead of defining FullAppDir directly in NSIS, we duplicate the functionality of ProgramExecutable and ProgramExecutable64 as FullAppDir and FullAppDir64 so that they can be manually decided by the developer, perhaps giving them sensible defaults so that the de facto standard is already in place for the developers/apps that follow it.

~3D1T0R

richo
richo's picture
Offline
Last seen: 11 hours 50 min ago
Joined: 2007-01-31 22:03
My Thoughts

I'm thinking of adding $FullAppDir by default, using ${AppName}64 and ${AppName} as the directory names referenced.

I vote for this (for the defaults), and if any dev releasing a portableapp doesn't like that structure (for whatever reason) allow for setting it how they would prefer.

Something like:
AppDirectory, AppDirectory64
or
ProgramDirectory, ProgramDirectory64
in the [Launch] section.

This would also mean that the directory no longer needs to be set in ProgramExecutable, ProgramExecutable64.

Though, thinking about it, that is probably how you would of done it anyway. (More or less)

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
I was thinking about that.

I was thinking about that, and while it might be good to base ProgramExecutable & ProgramExecutable64 on the location of FullAppDir, it would require changes to a number of app's configurations.
Note: I'm not saying it should or shouldn't be done this way, just that this is a factor to consider.

I think this might be good:

[Launch]
ProgramDirectory=AppName32
ProgramDirectory64=AppName64
ProgramExecutable=Bin\App.exe
ProgramExecutable64=Bin\App64.exe

[FilesMove]
settings\AppSettings.ini=%FullAppDir%\data

matching this structure:

AppNamePortable
+---App
|   +---AppName32
|   |   +---Bin
|   |   |   App.exe
|   |   \---data
|   |       AppSettings.ini (Gets moved here when running on 32-bit Windows)
|   \---AppName64
|       +---Bin
|       |   App64.exe
|       \---data
|           AppSettings.ini (Gets moved here when running on 64-bit Windows)
\---Data
    \---settings
        AppSettings.ini (stored here when not running)

Note: This is a simplified view of the structure, not showing unnecessary files & folders.
Note2: This is intentionally a slightly unusual app in order to show how both FullAppDir/FullAppDir64 and ProgramExecutable/ProgramExecutable64 may be needed in some apps.
Note3: After writing this all out I think I might prefer ProgramDirectory/ProgramDirectory64 as opposed to FullAppDir/FullAppDir64, but I need sleep so I'm going to stop writing. Goodnight.
Edit: I altered my example to use ProgramDirectory/ProgramDirectory64. %FullAppDir% would be built by adding the contents of ProgramDirectory to the end of the %PAL:AppDir% environment variable, and the execution string would be based on the contents of ProgramExecutable being added to the end of %FullAppDir%

~3D1T0R

JLim
Offline
Last seen: 1 month 1 week ago
Joined: 2013-07-17 01:30
I add the following 2 lines

I add the following 2 lines to the end of ${SegmentInit} in Core.nsh, ver. 2.2.1 of PAL. Seems work. Pls test.

${WordFind} $ProgramExecutable "\" "+01" $0
StrCpy $FullAppDir "$AppDirectory\$0"

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 1 week 1 day ago
DeveloperModerator
Joined: 2008-07-24 18:46
Thanks, implementation coming following feedback

Thanks for looking at it.

I've got an implementation in place for this already, it just may need tweaking depending on feedback in this thread, particularly from John.

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
What about %PAL:Bits%

I was just looking through the source of the PAL Manual in the repository, and the %PAL:Bits% environment variable stood out to me. Isn't the purpose of this effectively to replace the need for a %FullAppDir%, in that the directory should be able to be defined as AppName%PAL:Bits%, which by default would be AppName32 and AppName64, but could be defined via [Launch]:BitsVariable32> and [Launch]:BitsVariable64 to be x86 & x64 if the developer wished, making then AppNamex86 and AppNamex64, or even by defining [Launch]:BitsVariable32 as an empty string, one could make it AppName and AppName64.

To be honest, having looked at this again, I think %PAL:Bits% eliminates the need for %FullAppDir% and thus there's little reason to add it to PAL.

~3D1T0R

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 1 week 1 day ago
DeveloperModerator
Joined: 2008-07-24 18:46
Let's not reinvent the wheel!

Good catch, looks like we're reinventing the wheel.

However, I think I'm still going to define FullAppDir, as it's already in wide use, as %PAL:AppDir%\%AppName%%PAL:Bits%.
This allows the variable to continue to be used as it is now, in multiple places in launcher.ini.
I foresee that it may also see further adoption, for example in FilesMove and DirectoriesMove sections for in-package moves.

This way, for the apps using AppName64 and AppName, BitsVariable32 can be set to an empty string. (Provided that works, I need to test it.)
For those using AppNamex64 and AppName, BitsVariable64 can also be set to x64.
Lastly, those using AppName\x64 and AppName\x86, FullAppDir can be re-defined in the Environment section as %PAL:AppDir%\%AppName%\%PAL:Bits% after setting BitsVariable32 and 64 to x86 and x64 respectively.

demon.devin
demon.devin's picture
Offline
Last seen: 2 years 1 month ago
Developer
Joined: 2007-08-02 09:04
That's almost how I went
That's almost how I went ahead and structured my code. I'm using the variable $Bit to check if file system redirection needs to be turned on or off by using the variable $App and comparing it to ${APP64}. I also use it for checking a machines architecture by doing something like the following in the beginning of the .onInit function:
System::Call `kernel32::GetCurrentProcess()i.s`
System::Call `kernel32::IsWow64Process(is,*i.r0)`
StrCmpS $0 0 +3
StrCpy $Bit 64
Goto +2
StrCpy $Bit 32
!ifdef SYSTEMWIDE_DISABLEREDIR
	!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
		IntCmp $Bit 64 0 +2 +2
		System::Call `kernel32::Wow64EnableWow64FsRedirection(i0)`
	!else
		StrCmpS $APP ${APP64} 0 +2  ;= If the x64 folder exists in App directory
		System::Call `kernel32::Wow64EnableWow64FsRedirection(i0)`
	!endif
!endif
After all the Segments have been executed I then check and turn the file system redirection back on again:
!ifdef UAC
	${RunSegment} RunAsAdmin		;= Last Segment in .onInit
!endif
!ifdef SYSTEMWIDE_DISABLEREDIR
	!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
		IntCmp $Bit 64 0 +2 +2
		System::Call `kernel32::Wow64EnableWow64FsRedirection(i1)`
	!else
		StrCmpS $APP ${APP64} 0 +2
		System::Call `kernel32::Wow64EnableWow64FsRedirection(i1)`
	!endif
!endif
I set certain !define instructions that never change in construct using my favorite instruction ( =P ) !searchparse. It only changes with respect for the programs name. For instance, ${APP} will always hold the applications 32-bit folder name (7-Zip or IrfanView) whereas ${APP64} will always hold the 64-bit folder name (7-Zip64 or IrfanView64). If there's a 64-bit version of a program available than ${APP64} is just the short name or the AppID excluding the word "Portable" and appending the number 64. So now I can do something similar to the following code snippet for an application that has both a 32-bit and a 64-bit version (like in my 7-ZipPortable for example):
;= VARIABLES
Var App

;= DEFINES
!define 32     7-Zip\7zFM.exe 			;= These defines are used throughout the custom.nsh file
!define 64     7-Zip64\7zFM.exe
!define EXE32  `$EXEDIR\App\${32}`
!define EXE64  `$EXEDIR\App\${64}`
!define SET32  `Kernel32::SetEnvironmentVariable(t "7-ZIP", t "7-Zip")`
!define SET64  `Kernel32::SetEnvironmentVariable(t "7-ZIP", t "7-Zip64")`

;= CUSTOM
${Segment.OnInit}
	StrCmpS $Bit 32 +6
	IfFileExists `${EXE64}` 0 +5 		;= If user decided to keep the x64 version on install.
	SetRegView 64				;= I can now set the registry view accordingly.
	StrCpy $App ${APP64}			;= $App will now hold whatever ${APP64} is 
	System::Call `${SET64}`			;= Sets %7-ZIP% to contain 7-Zip64
	Goto +3
	StrCpy $App ${APP}			;= $App will be used within the custom.nsh file
	System::Call `${SET32}` 		;= Sets %7-ZIP% to contain 7-Zip
!macroend
Inside my 7-ZipPortable.ini launcher configuration file I may now do the following:
[Launch]
WorkingDirectory=%PAL:AppDir%\%7-ZIP%

[RegistryValueWrite]
HKCU\SOFTWARE\7-Zip\Path=REG_SZ:%PAL:AppDir%\%7-ZIP%\
HKCU\SOFTWARE\7-Zip\Path64=REG_SZ:%PAL:AppDir%\%7-ZIP%\
I'm pretty sure the above code can be done a bit more pragmatically allowing for a much more broad spectrum of portable apps and I realize that you guys I trying to discourage the use of the custom.nsh file but I just felt like sharing anyway. Sorry for going off-topic somewhat with the file system redirection tidbit. I just meant to agree with 3D1T0R and share how I have came to deal with this concept. Lol.

daemon.devin

John T. Haller
John T. Haller's picture
Offline
Last seen: 6 hours 27 min ago
AdminDeveloperModeratorTranslator
Joined: 2005-11-28 22:21
Vote for specifically defined AppName and AppName64

I'd like to have it defined somehow as AppName and AppName64, not AppName32. I've been using this as a standard structure for most released app since I started doing dual mode apps. If we have to reformat apps to be AppName32 and AppName64, that's going to require custom code in the installers to move files around for several apps (plugins, added fonts, mods, etc).

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

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
We'll have to check to verify that it works properly first, but…

We'll have to check to verify that it works properly first, but with the system Gord & I are considering, you should be able set it to work that way by simply defining [Launch]:BitsVariable32 as an empty string.
I'll try to test it soon, but I'd take a wild guess that Gord can probably get to it sooner than I.

If that doesn't work, then I suppose we could consider having the [Launch]:BitsVariable32 default be an empty string, and if you want it to be 32 (or something else) you have to set it yourself.

~3D1T0R

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 1 week 1 day ago
DeveloperModerator
Joined: 2008-07-24 18:46
AppName AppName64

I still need to do some testing, but I currently have BitsVariable32 defaulting to an empty string, which accomplishes exactly what we're wanting:

  • On a 32-bit system, %FullAppDir% is set to %PAL:AppDir%\%AppName%, ie. X:\PortableApps\BlenderPortable\App\Blender
  • On a 64-bit system, %FullAppDir% is set to %PAL:AppDir%\%AppName%64, ie. X:\PortableApps\BlenderPortable\App\Blender64

When required, this can be overrode using [Launch]: BitsVariable32 or 64.

[EDIT] Alternatively, we can remove the BitsVariable customization function.

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
You said there were a few apps that didn't fit that 'standard'.

Wouldn't it be best to keep it so that we don't have to make custom installer code for the apps you mentioned that use x86 and/or x64 directories?
Especially seeing how the BitsVariable customization is already written, present in the repository, and needs only to be used, I don't see why we would want to not use it. Do you?

~3D1T0R

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 1 week 1 day ago
DeveloperModerator
Joined: 2008-07-24 18:46
Customized here.

I've been looking into it, and the apps that don't meet what's becoming the standard have been placed in these other directory structures by our developers. As such, we can adjust the directories as needed.

Since the primary purpose of BitsVariable, and PAL:Bits is for FullAppDir customization (or at least that's as far as I can tell), in my opinion it'd be cleaner to implement FullAppDir directly.

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
I personally see no need for %FullAppDir% at all, and never have

Personally, I'd drop %FullAppDir% completely (I've thought it seemed rather out of place since I first started seeing it, and kept thinking that using %PAL:Bits% would make more sense.) and use what has been in the PAL source since 2011: %PAL:AppDir%\AppName%PAL:Bits%, but that's just what makes sense to me.

I was thinking about how environment variables generally seem to work on Windows, and I'm wondering if perhaps you're running into an issue where empty environment variables don't get 'expanded'. Is this an issue that you're hitting? is that why you're suddenly against it when you seemed like you were for it before? If so, it shouldn't be too difficult to remove 'unexpanded environment variables' after expanding them.

~3D1T0R

Gord Caswell
Gord Caswell's picture
Offline
Last seen: 1 week 1 day ago
DeveloperModerator
Joined: 2008-07-24 18:46
No issues encountered, good either way

I'm not running into any issues with empty environment variables.

I'm good with either way, however I'm thinking support-wise it may make more sense to use a method that's already in-use, and remove one that could replace it, but is not in use and adds further potential support problems.

That's not to say we couldn't figure out any problems as they arose - we are a smart group of folks, after all!
However, trying to alleviate the theoretical problem prior to it arising.

3D1T0R
3D1T0R's picture
Offline
Last seen: 1 year 2 months ago
Developer
Joined: 2006-12-29 23:48
Would %PAL:Bits% be available anyway?

I suppose, if %PAL:Bits% will be available too so that %PAL:AppDir%\AppName%PAL:Bits% can be used for non-standards-following apps, then it doesn't matter too much how %FullAppDir% is implemented, as situations that need a more custom solution can use %PAL:Bits%. After all, I still think %FullAppDir% doesn't really fit with the rest of PAL anyway.

~3D1T0R

Log in or register to post comments