!define MUI_PAGE_DIRECTORY_VARIABLE does not create variable - NSIS - nsis

I'm trying to create an NSIS script which copies various files to two different locations that can be specified.
I have checked the documentation and other StackOverflow entries but do not come up with a solution.
My Problem is that I want to define a second variable for a directory. In this directory sample files and projects shall be copied.
When trying to compile the NSI I get the following error/warnings:
3 warnings:
unknown variable/constant "APPDIR" detected, ignoring (C:\Users\max\Desktop\PortablePlayer\so.nsi:29)
unknown variable/constant "APPDIR" detected, ignoring (C:\Users\max\Desktop\PortablePlayer\so.nsi:33)
unknown variable/constant "APPDIR\Testfile.txt" detected, ignoring (C:\Users\max\Desktop\PortablePlayer\so.nsi:43)
Here is my script that I'm using:
!include "MUI.nsh"
Name "MyApp"
OutFile "MyApp-Installer.exe"
InstallDir "$PROGRAMFILES\My App"
; Installation Directory for the App
!insertmacro MUI_PAGE_DIRECTORY
; Installation Directory for the samples and projects
!define MUI_PAGE_HEADER_SUBTEXT "Choose your custom Samples Folder"
!define MUI_DIRECTORYPAGE_TEXT_TOP "To separate your App and your samples and projects you can choose a different folder than the installation directory"
!define MUI_PAGE_DIRECTORY_VARIABLE $APPDIR
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section ""
SetOutPath $INSTDIR
File Testfile.txt
SetOutPath $APPDIR
File Testfile.txt
FileOpen $0 "$DESKTOP\Hello_world.txt" w
FileWrite $0 $APPDIR
FileClose $0
WriteUninstaller "$INSTDIR\MyApp-Uninstaller.exe"
SectionEnd
Section "Uninstall"
Delete "$INSTDIR\Testfile.txt"
Delete "$INSTDIR\MyApp-Uninstaller.exe"
RMDir $INSTDIR
Delete "$APPDIR\Testfile.txt"
SectionEnd
For debugging I tried to write the value of $APPDIR into a textfile but it only writes $APPDIR instead of the value.
If I change it to $INSTDIR it prints the correct path for $INSTDIR.
How can I initialize the variable for $APPDIR?
If I try to initialize it on the top, it is there but empty, so the installer fails after succesful compilation of the script.
Running Win 7 with NSIS 2.5.1
Can anybody please shed some light on what is wrong?
Thanks!

The MUI_DIRECTORYPAGE_VARIABLE define tells MUI that you have a custom variable that you want to use but MUI does not create the variable, you have to do that yourself near the top of your script:
Var APPDIR
So it should look something like
Var APPDIR
!include "MUI.nsh"
!define MUI_DIRECTORYPAGE_VARIABLE $APPDIR
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section
DetailPrint $APPDIR
SectionEnd
Edit: The name of the define is MUI_DIRECTORYPAGE_VARIABLE not MUI_PAGE_DIRECTORY_VARIABLE like you have in your example...

Related

How to pass command line arguments when run after install with electron-builder NSIS installer

With electron-builder NSIS installer we're able to create an executable installer which launches the installed electron app immediately after the install is finished. My question is is there a way to pass any command line parameters the installer itself was launched with to the installed app on this first launch?
I have seen some NSIS custom scripts which suggest that an executable can be launched with Exec, and the installer parameters can be retrieved with GetParameters. Is that a recommended direction, or is there some configuration option either in electron-builder or NSIS?
EDIT:
Here is a possible solution:
set nsis.runAfterFinish electron-builder option to false (true is the default);
implement customInstall event handler to customize the normal electron-builder provided template:
!macro StartAppWithParameters
Var /GLOBAL startAppWithParametersArgs
${if} ${isUpdated}
StrCpy $startAppWithParametersArgs "--updated"
${else}
StrCpy $startAppWithParametersArgs ""
${endif}
${StdUtils.GetAllParameters} $R0 0
${StdUtils.ExecShellAsUser} $0 "$launchLink" "open" '$startAppWithParametersArgs $R0'
!macroend
!macro customInstall
HideWindow
!insertmacro StartAppWithParameters
!macroend
Details are in electron-builder NSIS configuration, and electron-builder NSIS template
Thanks!
Yes you can do it manually with Exec and GetParameters:
!include "FileFunc.nsh"
!include "MUI2.nsh"
!macro RunWithInstallersParameters app
Push "${app}"
Call RunWithInstallersParameters
!macroend
Function RunWithInstallersParameters
Exch $0
Push $1
${GetParameters} $1
Exec '"$0" $1'
Pop $1
Pop $0
FunctionEnd
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION MyFinishRun
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function MyFinishRun
!insertmacro RunWithInstallersParameters "$sysdir\Calc.exe"
FunctionEnd
Section
SetOutPath $InstDir
File "blahblah"
!insertmacro RunWithInstallersParameters "$windir\Notepad.exe"
SectionEnd
The MUI Finish page also supports a way to specify the parameters directly but since we don't know the parameters at compile time we have to use a variable:
!include "FileFunc.nsh"
!include "MUI2.nsh"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN "$windir\Notepad.exe"
!define MUI_FINISHPAGE_RUN_PARAMETERS $1 ; Initialized by our MUI_PAGE_CUSTOMFUNCTION_SHOW function
!define MUI_PAGE_CUSTOMFUNCTION_SHOW InitFinishPage
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function InitFinishPage
${GetParameters} $1
FunctionEnd
I don't know anything about electron-builder but I assume there is a way for you to customize the NSIS script somehow.

With NSIS can I share values between MUI_PAGE_DIRECTORY pages?

I have two MUI_PAGE_DIRECTORY pages. The first stores the entered data to the default, $INSTDIR. What I would like to do is copy the value in $INSTDIR to the defined var $DataDir so that before the second directory page is displayed, $DataDir becomes $INSTDIR\Data. When the second page is displayed I would like the default value to be $INSTDIR\Data.
Is this possible?
InstallDir $ProgramFiles\MyApp
Var DataDir
!include MUI2.nsh
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE InstDirPageLeave
!insertmacro MUI_PAGE_DIRECTORY
!define MUI_DIRECTORYPAGE_VARIABLE $DataDir
!define MUI_DIRECTORYPAGE_TEXT_TOP "Choose Data directory for bla bla bla..."
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Data Directory:"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW DataDirShowPage
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Function InstDirPageLeave
StrCpy $DataDir "$InstDir\Data"
FunctionEnd
Function DataDirShowPage
!insertmacro MUI_HEADER_TEXT "Foo" "Bar"
FunctionEnd
Section
DetailPrint $InstDir
DetailPrint $DataDir
SectionEnd
What are you trying to achieve?
If you want to install some files into two separate locations use MUI_PAGE_DIRECTORY and custom nsDialogs page (with browse folder button) so user can pick up two directories.
If your location is always $INSTDIR and second is somewhere inside it ($INSTDIR\some\data\path) then you only need to append your inside path to $INSTDIR - there is no need to show dialog twice and select path twice.

Creating shortcut with NSIS

I am trying to create an installer using NSIS, installing just the program that I have made works just fine but when I add code to the script to install a shortcut as well things aren't working.
I am very new to this program and what happens is the "Start in:" property path is incomplete but if i add the "\IndieBrowser\IndieBrowser\bin\Debug\IndieBrowser.exe"" at the end it just turns a lot of things into folders.
Full code:
!include "MUI2.nsh"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section "Desktop Shortcut" SectionS
SetShellVarContext current
SetOutPath "$INSTDIR"
CreateShortCut "$DESKTOP\IndieBrowser.lnk" "$INSTDIR\IndieBrowser\IndieBrowser\bin\Debug\IndieBrowser.exe"
SectionEnd
Here is an example:
; Create application shortcut (first in installation dir to have the correct "start in" target)
SetOutPath "$INSTDIR\bin"
CreateShortCut "$INSTDIR\bin\${NAME}.lnk" "$INSTDIR\bin\${NAME}.exe"
; Start menu entries
SetOutPath "$SMPROGRAMS\${NAME}\"
CopyFiles "$INSTDIR\bin\${NAME}.lnk" "$SMPROGRAMS\${NAME}\"
Delete "$INSTDIR\bin\${NAME}.lnk"

Require Component Installation with MUI

As a new NSIS user, I have defaulted to the HM NIS Edit wizard to create my installers so far. The default output takes advantage of MUI, which has been very useful to me. It also, however, includes a components page from the MUI macro library, so I cannot pick and choose which components are mandatory. I have looked at this question: How to make a SectionGroup mandatory in NSIS script, but I'm not sure where to put it in my code below, or even how to modify the wizard's output code to include it. The installer is for several apps with distinct (selectable) executables that all require the same (ideally mandatory) support files.
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "Product"
!define PRODUCT_VERSION "1.0"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\App1.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
; MUI 1.67 compatible ------
!include "MUI.nsh"
; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES
; Language files
!insertmacro MUI_LANGUAGE "English"
; MUI end ------
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "Setup.exe"
InstallDir "$PROGRAMFILES\Product"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show
Section "Support Files" SEC01
SetOutPath "$INSTDIR"
SetOverwrite try
File "..\Support\File\Path\file.txt"
SectionEnd
Section "App1" SEC02
SetOutPath "$INSTDIR"
SetOverwrite try
File "..\App1\File\Path\App1.exe"
SectionEnd
Section "App2" SEC03
SetOutPath "$INSTDIR"
SetOverwrite try
File "..\App2\File\Path\App2.exe"
SectionEnd
In short, I need to know how to make the Support Files section mandatory, without losing the GUI. My only experience, though, is with the above-mentioned wizard.
The SectionIn instruction is used to assign sections to install types (Combobox on the components page) but it can also make sections read-only:
Section "Support Files" SEC01
SectionIn RO ;Make it read-only
SetOutPath "$INSTDIR"
SetOverwrite try
File "..\Support\File\Path\file.txt"
SectionEnd

NSIS Installer Start Menu Directory

I have an NSIS installer that has the start menu folders hard-coded using this code...
Var SMDir ;Start menu folder
!insertmacro MUI_PAGE_STARTMENU 0 $SMDir
Section -StartMenu
!insertmacro MUI_STARTMENU_WRITE_BEGIN 0
CreateDirectory "$SMPrograms\MY Program\My Folder"
CreateShortCut "$DESKTOP\My Program" "$INSTDIR\start.exe"
CreateShortCut "$SMPROGRAMS\MY Program\My Shortcut.lnk" "$INSTDIR\start.exe"
CreateShortCut "$SMPROGRAMS\My Program\Uninstall.lnk" "$INSTDIR\uninstall.exe"
This all works apart from on the 'Choose Start Menu Folder' it doesn't let me change the default installation directory.
Is there a way to fix this or alternatively how can I skip this page but still trigger the StartMenu section?
If you don't want a startmenu selection page at all just remove !insertmacro MUI_PAGE_STARTMENU ... and the two !insertmacro MUI_STARTMENU_* macros in the -StartMenu section.
If you want to allow the user to choose the directory then you must use the variable and not hardcode the path:
outfile test.exe
name "SM Test"
requestexecutionlevel user ;Single user/"Just me" installer
!define MUI_COMPONENTSPAGE_NODESC
!include mui2.nsh
Var SMDir ;Start menu folder
!insertmacro MUI_PAGE_COMPONENTS
;!define MUI_STARTMENUPAGE_DEFAULTFOLDER "MY Program" ;Default, name is used if not defined
!insertmacro MUI_PAGE_STARTMENU 0 $SMDir
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Section -StartMenu
!insertmacro MUI_STARTMENU_WRITE_BEGIN 0 ;This macro sets $SMDir and skips to MUI_STARTMENU_WRITE_END if the "Don't create shortcuts" checkbox is checked...
CreateDirectory "$SMPrograms\$SMDir"
CreateShortCut "$SMPROGRAMS\$SMDir\Myapp.lnk" "$INSTDIR\start.exe"
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
Section "Desktop Shortcut"
CreateShortCut "$DESKTOP\Myapp.lnk" "$INSTDIR\start.exe"
SectionEnd
(If you are installing as administrator then you should call SetShellVarContext all before accessing $SMPrograms and you should probably not create a desktop shortcut)

Resources