Installing mutual exclusive Versions of Programs: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(First)
 
(Fix explanation due to initial false assumption about directory structure in installers)
 
Line 1: Line 1:
An undocumented side effect of <span style="font-family: monospace, monospace;">SetOutPath</span> is
[https://7-zip.org/ 7-Zip] allows to unpack NSIS installers which is occasionally very useful.
that it also affects the directory where the files specified by
There is no directory structure in an installer.
<span style="font-family: monospace, monospace;">File</span> are located in the installer archive.
7-zip heuristically tries the deduce the installed directory structure by analyzing the NSIS script,
in particular from the compiled versions of
<span style="font-family: monospace, monospace;">SetOutPath</span> statements.


The order in the source file instead of the execution order during installation is relevant in this case.
The static order in the script instead of the execution order during installation is relevant in this case.
This difference could be used to place mutual exclusive versions of programs in separate archive
This could be used to let 7-Zip unpack files to subdirectories which differ from installation subdirectories.
directories.
 
This assumes that this undocumented feature will not be changed in future NSIS releases.


For a real world use case, please see the
For a real world use case, please see the
Line 32: Line 31:
     ${IfNot} ${SectionIsSelected} ${X64}
     ${IfNot} ${SectionIsSelected} ${X64}
       Goto +2
       Goto +2
         SetOutPath "$INSTDIR\bin32" ; never executed but sets archive dir to 'bin32'
         SetOutPath "$INSTDIR\bin32" ; never executed but sets unpack dir to 'bin32'
       File 'build\x86\${name}'
       File 'build\x86\${name}'
     ${Else}
     ${Else}
       Goto +2
       Goto +2
         SetOutPath "$INSTDIR\bin64" ; never executed but sets archive dir to 'bin64'
         SetOutPath "$INSTDIR\bin64" ; never executed but sets unpack dir to 'bin64'
       File 'build\x86_64\${name}'
       File 'build\x86_64\${name}'
     ${EndIf}
     ${EndIf}
   !macroend
   !macroend


   SetOutPath "$INSTDIR" ; sets install path
   SetOutPath "$INSTDIR\bin" ; sets install path
   !insertmacro FileExe "one.exe"
   !insertmacro FileExe "one.exe"
   !insertmacro FileExe "two.exe"
   !insertmacro FileExe "two.exe"
SectionEnd
SectionEnd
</highlight-nsis>
</highlight-nsis>


The installer will then contain the following directories and files:
7-Zip will then detect the following path names:


   bin32/one.exe
   bin32/one.exe
Line 55: Line 53:
   bin64/two.exe
   bin64/two.exe


The following files will be installed from either
Without the skipped <span style="font-family: monospace, monospace;">SetOutPath</span>
<span style="font-family: monospace, monospace;">bin32</span> or
statements, 7-Zip would detect the following path names:
<span style="font-family: monospace, monospace;">bin64</span> directory:


   $INSTDIR/one.exe
   bin/one.exe
   $INSTDIR/two.exe
   bin/one.exe
  bin/two.exe
  bin/two.exe


It would then be impossible to unpack both variants at once.
[[Category:Code Examples]]
[[Category:Code Examples]]

Latest revision as of 14:31, 12 January 2026

7-Zip allows to unpack NSIS installers which is occasionally very useful. There is no directory structure in an installer. 7-zip heuristically tries the deduce the installed directory structure by analyzing the NSIS script, in particular from the compiled versions of SetOutPath statements.

The static order in the script instead of the execution order during installation is relevant in this case. This could be used to let 7-Zip unpack files to subdirectories which differ from installation subdirectories.

For a real world use case, please see the smartmontools installer.

Example

Name "Installer"
OutFile "install.exe"
RequestExecutionLevel user
InstallDir "$DESKTOP\nsis-test"
 
!include "LogicLib.nsh"
 
Page components
Page instfiles
 
Section "64-bit version" X64
SectionEnd
 
Section "Programs"
  !macro FileExe name
    ${IfNot} ${SectionIsSelected} ${X64}
      Goto +2
        SetOutPath "$INSTDIR\bin32" ; never executed but sets unpack dir to 'bin32'
      File 'build\x86\${name}'
    ${Else}
      Goto +2
        SetOutPath "$INSTDIR\bin64" ; never executed but sets unpack dir to 'bin64'
      File 'build\x86_64\${name}'
    ${EndIf}
  !macroend
 
  SetOutPath "$INSTDIR\bin" ; sets install path
  !insertmacro FileExe "one.exe"
  !insertmacro FileExe "two.exe"
SectionEnd

7-Zip will then detect the following path names:

 bin32/one.exe
 bin64/one.exe
 bin32/two.exe
 bin64/two.exe

Without the skipped SetOutPath statements, 7-Zip would detect the following path names:

 bin/one.exe
 bin/one.exe
 bin/two.exe
 bin/two.exe

It would then be impossible to unpack both variants at once.