You are here

Different executables for different Windows versions?

6 posts / 0 new
Last post
Fayne Aldan
Offline
Last seen: 11 months 2 weeks ago
Joined: 2022-08-14 13:37
Different executables for different Windows versions?

Hello. I want to make my portable app change ProgramExecutable based on the version of Windows. I tried to this in Custom.nsh:

${SegmentFile}

${SegmentInit}
    ${If} ${AtLeastWin110}
        ${SetEnvironmentVariablesPath} FullAppDir $AppDirectory\PolyMC
    ${Else}
        ${SetEnvironmentVariablesPath} FullAppDir $AppDirectory\Legacy
    ${EndIf}
!macroend

But it seems I can't use the environment variable in ProgramExecutable. Any idea how I'd accomplish this? Thanks.

John T. Haller
John T. Haller's picture
Offline
Last seen: 3 hours 57 min ago
AdminDeveloperModeratorTranslator
Joined: 2005-11-28 22:21
Custom Code

At the moment the AtLeastWinX variables don't work for Windows 10 and 11 in the PA.c Launcher, so you'll need to use custom code. For an example of this, check out the custom code in the current calibre Portable launcher. Here's a simplified version that should work for your use case:

${SegmentFile}

${SegmentInit}
	ReadRegStr $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentBuild"

	${If} $0 > 9999 ;Windows 10 or later
		${SetEnvironmentVariablesPath} FullAppDir $AppDirectory\PolyMC
	${Else}
		${SetEnvironmentVariablesPath} FullAppDir $AppDirectory\Legacy
	${EndIf}
!macroend

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

Fayne Aldan
Offline
Last seen: 11 months 2 weeks ago
Joined: 2022-08-14 13:37
Hello. Thanks for the answer.

Hello. Thanks for the answer. Unfortunately, it would seem that I still can't use the FullAppDir variable in ProgramExecutable. It just tells me "App\%FullAppDir%\PolyMC.exe could not be found". So, environment variables don't seem to be expanded in ProgramExecutable. I get the same result if I try to put in a different variable, like %AppData% (for testing). Looking at calibre's custom code, it looks like it's renaming the included Calibre64 and Calibre32 directories to Calibre and launching from the Calibre directory. I did figure out a better solution, however. I can use StrCpy to change $ProgramExecutable in my code. However, if I change it in Init, it's read from config afterwards in Core.nsh. I had to change the variable in Pre. It's worth noting, however, that normally ProgramExecutable is checked to make sure it exists during Init, so I just set the config to the Win10 version of my application and changed it to Legacy if needed.

${SegmentFile}

${SegmentPre}
    ReadRegStr $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentBuild"

    ${If} $0 < 10000
        StrCpy $ProgramExecutable "Legacy\PolyMC.exe"
    ${EndIf}
!macroend
John T. Haller
John T. Haller's picture
Offline
Last seen: 3 hours 57 min ago
AdminDeveloperModeratorTranslator
Joined: 2005-11-28 22:21
Move

Ah right. I forgot you were using it for ProgamExecutable. That variable doesn't support environment variables within the PA.c Launcher at present. Your alternative would be to move either the EXE or the directories the way I do in calibre. Here's an example with PolyMC always being the directory and moving the legacy vs modern to it depending on OS:

${SegmentFile}

${SegmentInit}
	ReadRegStr $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentBuild"

	${If} $0 > 9999 ;Windows 10 or later
		${If} ${FileExists} "$EXEDIR\App\PolyMC-Modern"
			Rename "$EXEDIR\App\PolyMC" "$EXEDIR\App\PolyMC-Legacy"
			Rename "$EXEDIR\App\PolyMC-Modern" "$EXEDIR\App\PolyMC"
		${EndIf}
	${Else}
		${If} ${FileExists} "$EXEDIR\App\PolyMC-Legacy"
			Rename "$EXEDIR\App\PolyMC" "$EXEDIR\App\PolyMC-Modern"
			Rename "$EXEDIR\App\PolyMC-Legacy" "$EXEDIR\App\PolyMC"
		${EndIf}
	${EndIf}
!macroend

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

Fayne Aldan
Offline
Last seen: 11 months 2 weeks ago
Joined: 2022-08-14 13:37
As I mentioned above, a

As I mentioned above, a better alternative is to change $ProgramExecutable in SegmentPre:

${SegmentFile}

${SegmentPre}
    ReadRegStr $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentBuild"

    ${If} $0 < 10000
        StrCpy $ProgramExecutable "Legacy\PolyMC.exe"
    ${EndIf}
!macroend

(For some reason, < and " are escaped in that code block when using Markdown)

Edit: If you do it in Init instead of Pre, it's read from the INI afterwards. I have the "Modern" version defined in the INI, because PA Launcher also checks to make sure the path exists during Init.

John T. Haller
John T. Haller's picture
Offline
Last seen: 3 hours 57 min ago
AdminDeveloperModeratorTranslator
Joined: 2005-11-28 22:21
Ah Right

Ah, right, sorry about that. Yes, this solution should work.

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

Log in or register to post comments