This article briefly describes how to make installers for Windows that can handle the multiple installation paths that a VST or more generally a plugin installer might need to deal with.
Installing NSIS
You can install NSIS from their website. You then
should ideally add the install path to the PATH environnement variable in order to be able
to call the makensis
command from any command line shell.
Simply search for "environnement variables" from the start menu, and you should see an entry for the appropriate configuration panel.
Once you're done, you can check that it worked by opening a new Powershell session and typing
makensis
. if you get a message saying that this command is not recognised, you provided the wrong
path for the environnement variable. A quick way to double check that is to type Get-ChildItem env:
and look for the PATH
variable.
Writing the NSIS file
NSIS provides a scripting language for .nsi
files where the installer and uninstaller are described.
Writing this file is mostly about describing the files to be copied, and the installer and uninstaller
pages.
I'm going to assume you already have built your software or plugin locally, and that all binaries or libraries are ready to be shipped into the installer.
The following code describes a typical installer for a 64bits VST plugin, with a standalone binary and a VST3 plugin folder.
; this NSIS plugin provides a modern user interface
!include "MUI2.nsh"
; this is the name of your software
Name "ExamplePlugin"
; this variable will hold the vst installation path the user picked
Var VstInstDir
!define APP_NAME "ExamplePlugin"
!define APP_VERSION "1.0.0"
!define APP_DIR "$PROGRAMFILES64\MyCompany\${APP_NAME}"
!define APP_ICON "exampleplugin.ico"
; this is a customized finish page text
!define MUI_FINISHPAGE_TEXT "Thank you for installing ExamplePlugin."
; icon for the installer and uninstaller (needs to be in the same folder where the makensis command is called)
!define MUI_ICON "exampleplugin.ico"
!define MUI_UNICON "exampleplugin.ico"
; your optional end user agreement page texts, not that later we will include a text file with the full license
!define MUI_LICENSE_PAGE_TITLE "End User License Agreement"
!define MUI_LICENSE_PAGE_TEXT "Please read the following license agreement carefully."
!define MUI_LICENSE_PAGE_CUSTOMTEXT "This license applies to both the binary and the VST3 plugin software."
!define MUI_TEXT_LICENSE_TITLE "End User License Agreement"
; defines the output name of the installer
Outfile "${APP_NAME}-${APP_VERSION}-Install.exe"
; defines the main installation folder (user can customize it)
InstallDir "${APP_DIR}"
; this ensures the installer has admin rights
RequestExecutionLevel admin
; this section is the main installing procedure
Section "MainSection" SEC01
; this part covers the app installation directory
SetOutPath "$INSTDIR"
File "..\build\src\ExampleApp\ExampleApp.exe"
File "exampleplugin.ico"
; and this part will take care of copying the vst plugin to the location picked by user
SetOutPath "$VstInstDir\ExamplePlugin.vst3"
; the /r is for recursive (as it's a folder)
File /nonfatal /a /r "..\build\src\ExamplePlugin\ExamplePlugin_artefacts\Release\VST3\ExamplePlugin.vst3\" #note back slash at the end
; this will create the startmenu shortcut
CreateShortCut "$SMSTARTUP\ExampleApp.lnk" "$INSTDIR\ExampleApp.exe" "" "$INSTDIR\ExampleApp.exe,0"
CreateShortCut "$SMPROGRAMS\MyCompany\ExampleApp.lnk" "$INSTDIR\ExampleApp.exe" "" "$INSTDIR\exampleplugin.ico" 0
; this will write an uninstaller to the install location
WriteUninstaller "$INSTDIR\${APP_NAME}-${APP_VERSION}-Uninstall.exe"
SectionEnd
; here we describe all the files to be removed during uninstallation
Section "Uninstall"
Delete "$INSTDIR\ExampleApp.exe"
Delete "$INSTDIR\exampleplugin.ico"
Delete "$SMPROGRAMS\MyCompany\ExampleApp.lnk"
Delete "$SMSTARTUP\ExampleApp.lnk"
Delete "$INSTDIR\${APP_NAME}-${APP_VERSION}-Uninstall.exe"
RMDir /r "$VstInstDir\ExamplePlugin.vst3"
RMDir "$INSTDIR"
SectionEnd
; this instantiates some variables and ensure folder exists, as well as setting 64bits paths
Function .onInit
SetRegView 64
CreateDirectory "$SMPROGRAMS\MyCompany"
StrCpy $VstInstDir "$PROGRAMFILES64\Common Files\VST3"
FunctionEnd
; this instantiates the same kind of things but for the uninstaller
Function un.onInit
SetRegView 64
StrCpy $VstInstDir "$PROGRAMFILES64\Common Files\VST3"
FunctionEnd
; then we proceed to describe all the page with MUI plugin macros
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "EULA.txt"
!insertmacro MUI_PAGE_DIRECTORY # this open a first time the browser page to set INSTDIR (default variable)
; we then proceed to set variables that will apply to the next MUI_PAGE_DIRECTORY page.
; Note that we also change MUI_DIRECTORYPAGE_VARIABLE, which will cause the directory page
; to change this new variable instead of INSTDIR
!define MUI_PAGE_HEADER_TEXT "Steinberg VST3 plugin location"
!define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install the ExamplePlugin VST3 plugin."
!define MUI_DIRECTORYPAGE_TEXT_TOP "The installer will install the VST3 plugin for the ExampleApp in the following folder. To install in a differenct folder, click Browse and select another folder. Click Next to continue."
!define MUI_DIRECTORYPAGE_VARIABLE $VstInstDir
!insertmacro MUI_PAGE_DIRECTORY # and here we open the directory page with our custom settings
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; the same process will apply to the uninstaller.
; Note that we could very much have registered the VST3 install location in the Windows registry
; instead of asking for it again.
!insertmacro MUI_UNPAGE_WELCOME
!define MUI_PAGE_HEADER_TEXT "Steinberg VST3 plugin location"
!define MUI_PAGE_HEADER_SUBTEXT "Choose the folder the ExamplePlugin VST3 plugin was installed to."
!define MUI_DIRECTORYPAGE_TEXT_TOP "The uninstaller will remove the VST3 plugin from the following folder. Click Next to continue."
!define MUI_DIRECTORYPAGE_VARIABLE $VstInstDir
!insertmacro MUI_UNPAGE_DIRECTORY
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
; finally we tell the installer to default to english
!insertmacro MUI_LANGUAGE "English"
The trick with this script is to display two "directory" pages with different settings in order to allow users to specify the VST3 install location that we can reuse during the main installing section.
If like me you are running makensis from a Gitlab Windows CI runner, you can quickly replace the version number with an environnement variable for a version tag using:
(Get-Content installer.nsi).Replace('1.0.0', ${env:CI_COMMIT_TAG}) | Set-Content installer.nsi
And if you are using MSVC, you can load a 64bits environnement for Powershell with the following two lines:
Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
Enter-VsDevShell -SkipAutomaticLocation -SetDefaultWindowTitle -InstallPath "C:\Program Files\Microsoft Visual Studio\2022\Community\" -DevCmdArguments "-arch=x64 -no_logo"