One Installer with Different Installation Files Each Time

From NSIS Wiki
Jump to navigationJump to search
Author: Red Wine (talk, contrib)


Links

Description

User Chilli24 wrote on forum thread:
I want to have a generic setup script to install some patches for my application. And because different patches may contain different files, I do not want to be forced to reedit the script when those files change. I want just to edit an .ini file and the NSIS compiler should look at that file and get from there the files.
There are at least three ways to figure this. Either with RecFind (my choice), or with Locate function, or just with File Instruction. Though, the disadvantage of the last choise is that we have not a full detailed files list.
For the example below, we call our installer skeleton, and we build in the same dir where our installation script resides, the file named CreateHeader. The purpose of CreateHeader is to prepare the files list for our installer.
Therefore, we only need to edit the patch type define each time we want to add new files to our installation. [edit]Code added by JasonFriday13[/edit].
Optional, we can have recursively included subdirs by changing our code. See the examples below.

  • Applies to NSIS 2.15

The Installer

name 'skeleton'
outfile 'skeleton.exe'
InstallDir '$PROGRAMFILES\MyApp'
 
;[added and edited by JasonFriday13]
!define PatchType 'Patch1_Files'
!define PatchPath 'C:\${PatchType}' 
 
!system '"${NSISDIR}\makensis.exe" /D PatchDir "${PatchPath}" /D Header "${PatchType}.nsh" "CreateHeader.nsi"'
!system 'CreateHeader.exe'
 
Section -
!addincludedir '.'
!include '${PatchType}.nsh'
SectionEnd
;[end edit]

Example 1 CreateHeader.exe Using RecFind.nsh

;[edited by JasonFriday13]
;!define PatchDir 'D:\Test Installation'
;!define Header 'Patch1_Files.nsh'
;[end edit]
 
OutFile 'CreateHeader.exe'
silentinstall silent
 
 
!include RecFind.nsh
 
Section
  SetOutPath '$EXEDIR'
  FileOpen $R2 ${Header} w
  ${RecFindOpen} "${PatchDir}" $R0 $R1
   FileWrite $R2 'SetOutPath "$$INSTDIR$R0"$\r$\n'
  ${RecFindFirst}
   FileWrite $R2 'File "${PatchDir}$R0\$R1"$\r$\n'
  ${RecFindNext}
  ${RecFindClose}
  FileClose $R2
SectionEnd

Example 2 CreateHeader.exe Using Locate function

;[edited by JasonFriday13]
;!define PatchDir 'D:\Test Installation'
;!define Header 'Patch1_Files.nsh'
;[end edit]
 
OutFile 'CreateHeader.exe'
silentinstall silent
 
!include "FileFunc.nsh"
!insertmacro Locate
 
Section
   SetOutPath '$EXEDIR'
   StrCpy $R0 ''
   StrLen $R1 '${PatchDir}'
   FileOpen $R2 '${Header}' w
   FileWrite $R2 'SetOutPath "$$INSTDIR"$\r$\n'
  # /G=1 Include sudirs. G=0 No subdirs. 
   ${Locate} "${PatchDir}" "/L=F /M=*.* /G=1" "LocateCallBack"
   FileClose $R2
   IfErrors 0 +2
   MessageBox MB_OK "Error" IDOK +2
SectionEnd
 
Function LocateCallBack
   StrCpy $1 $R8 '' $R1
   StrCmp $R0 $1 +3
   StrCpy $R0 $1
   FileWrite $R2 'SetOutPath "$$INSTDIR$R0"$\r$\n'
   FileWrite $R2 'File "$R9"$\r$\n'
   Push $0
FunctionEnd

Example 3 CreateHeader.exe Using File Instruction

Section
   SetOutPath '$EXEDIR'
   FileOpen $R2 ${Header} w
   FileWrite $R2 'SetOutPath "$$INSTDIR"$\r$\n'
   # File /r Include subdirs. File No subdirs.
   FileWrite $R2 'File /r  "${PatchDir}\*"$\r$\n'
   FileClose $R2
SectionEnd

License

This working example code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this code.

Permission is granted to anyone to use this script for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this code must not be misrepresented; you must not claim that you wrote the original script. If you use this script in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  2. Altered versions must be plainly marked as such, and must not be misrepresented as being the original code.
  3. This notice may not be removed or altered from any distribution.