/* This example script installs a simple application for a single user. If multiple users on the same machine run this installer, each user will end up with a separate install that is not affected by update/removal operations performed by other users. Per-user installers should only write to HKCU and folders inside the users profile. */ !define NAME "Per-user example" !define REGPATH_UNINSTSUBKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" Name "${NAME}" OutFile "Install ${NAME}.exe" Unicode True RequestExecutionLevel User ; We don't need UAC elevation InstallDir "" ; Don't set a default $InstDir so we can detect /D= and InstallDirRegKey InstallDirRegKey HKCU "${REGPATH_UNINSTSUBKEY}" "UninstallString" !include LogicLib.nsh !include WinCore.nsh !include Integration.nsh Page Directory Page InstFiles Uninstpage UninstConfirm Uninstpage InstFiles Function .onInit SetShellVarContext Current ${If} $InstDir == "" ; No /D= nor InstallDirRegKey? GetKnownFolderPath $InstDir ${FOLDERID_UserProgramFiles} ; This folder only exists on Win7+ StrCmp $InstDir "" 0 +2 StrCpy $InstDir "$LocalAppData\Programs" ; Fallback directory StrCpy $InstDir "$InstDir\$(^Name)" ${EndIf} FunctionEnd Function un.onInit SetShellVarContext Current FunctionEnd Section "Program files (Required)" SectionIn Ro SetOutPath $InstDir WriteUninstaller "$InstDir\Uninst.exe" WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "DisplayName" "${NAME}" WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "DisplayIcon" "$InstDir\MyApp.exe,0" WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "UninstallString" '"$InstDir\Uninst.exe"' WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "QuietUninstallString" '"$InstDir\Uninst.exe" /S' WriteRegDWORD HKCU "${REGPATH_UNINSTSUBKEY}" "NoModify" 1 WriteRegDWORD HKCU "${REGPATH_UNINSTSUBKEY}" "NoRepair" 1 !tempfile APP !makensis '-v2 "-DOUTFILE=${APP}" "-DNAME=NSISPerUserAppExample" -DCOMPANY=Nullsoft "AppGen.nsi"' = 0 File "/oname=$InstDir\MyApp.exe" "${APP}" ; Pretend that we have a real application to install !delfile "${APP}" SectionEnd Section "Start Menu shortcut" CreateShortcut /NoWorkingDir "$SMPrograms\${NAME}.lnk" "$InstDir\MyApp.exe" SectionEnd /* This Section registers a fictional .test-nullsoft file extension and the Nullsoft.Test ProgId. Proprietary file types are encouraged (by Microsoft) to use long file extensions and ProgIds that include the company name. When registering with "Open With" your executable should ideally have a somewhat unique name, otherwise there could be a naming collision with a different application (with the same name) installed on the same machine. REGISTER_DEFAULTPROGRAMS is not defined because proprietary file types do not typically use the Default Programs functionality. If your application registers a standard file type such as .mp3 or .html or a protocol like HTTP it should register as a Default Program. It should also register as a client (https://docs.microsoft.com/en-us/windows/win32/shell/reg-middleware-apps#common-registration-elements-for-all-client-types). */ !define ASSOC_EXT ".test-nullsoft" !define ASSOC_PROGID "Nullsoft.Test" !define ASSOC_VERB "MyApp" !define ASSOC_APPEXE "MyApp.exe" Section -ShellAssoc # Register file type WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\DefaultIcon" "" "$InstDir\${ASSOC_APPEXE},0" ;WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}" "" "Nullsoft Test App" [Optional] ;WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}" "MUIVerb" "@$InstDir\${ASSOC_APPEXE},-42" ; WinXP+ [Optional] Localizable verb display name WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}\command" "" '"$InstDir\${ASSOC_APPEXE}" "%1"' WriteRegStr ShCtx "Software\Classes\${ASSOC_EXT}" "" "${ASSOC_PROGID}" # Register "Open With" [Optional] WriteRegNone ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithList" "${ASSOC_APPEXE}" ; Win2000+ [Optional] ;WriteRegNone ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithProgids" "${ASSOC_PROGID}" ; WinXP+ [Optional] WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\shell\open\command" "" '"$InstDir\${ASSOC_APPEXE}" "%1"' WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}" "FriendlyAppName" "Nullsoft Test App" ; [Optional] WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}" "ApplicationCompany" "Nullsoft" ; [Optional] WriteRegNone ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\SupportedTypes" "${ASSOC_EXT}" ; [Optional] Only allow "Open With" with specific extension(s) on WinXP+ # Register "Default Programs" [Optional] !ifdef REGISTER_DEFAULTPROGRAMS WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities" "ApplicationDescription" "Shell association example test application" WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities\FileAssociations" "${ASSOC_EXT}" "${ASSOC_PROGID}" WriteRegStr ShCtx "Software\RegisteredApplications" "Nullsoft Test App" "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities" !endif ${NotifyShell_AssocChanged} SectionEnd Section -un.ShellAssoc # Unregister file type ClearErrors DeleteRegKey ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}" DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_PROGID}\shell" ${IfNot} ${Errors} DeleteRegKey ShCtx "Software\Classes\${ASSOC_PROGID}\DefaultIcon" ${EndIf} ReadRegStr $0 ShCtx "Software\Classes\${ASSOC_EXT}" "" DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_PROGID}" ${IfNot} ${Errors} ${AndIf} $0 == "${ASSOC_PROGID}" DeleteRegValue ShCtx "Software\Classes\${ASSOC_EXT}" "" DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}" ${EndIf} # Unregister "Open With" DeleteRegKey ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}" DeleteRegValue ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithList" "${ASSOC_APPEXE}" DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithList" DeleteRegValue ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithProgids" "${ASSOC_PROGID}" DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithProgids" DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}" # Unregister "Default Programs" !ifdef REGISTER_DEFAULTPROGRAMS DeleteRegValue ShCtx "Software\RegisteredApplications" "Nullsoft Test App" DeleteRegKey ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities" DeleteRegKey /IfEmpty ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}" !endif # Attempt to clean up junk left behind by the Windows shell DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Search\JumplistData" "$InstDir\${ASSOC_APPEXE}" DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$InstDir\${ASSOC_APPEXE}.FriendlyAppName" DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$InstDir\${ASSOC_APPEXE}.ApplicationCompany" DeleteRegValue HKCU "Software\Microsoft\Windows\ShellNoRoam\MUICache" "$InstDir\${ASSOC_APPEXE}" ; WinXP DeleteRegValue HKCU "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store" "$InstDir\${ASSOC_APPEXE}" DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "${ASSOC_PROGID}_${ASSOC_EXT}" DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "Applications\${ASSOC_APPEXE}_${ASSOC_EXT}" DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}\OpenWithProgids" "${ASSOC_PROGID}" DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}\OpenWithProgids" DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}\OpenWithList" DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}" ;DeleteRegKey HKCU "Software\Microsoft\Windows\Roaming\OpenWith\FileExts\${ASSOC_EXT}" ;DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs\${ASSOC_EXT}" ${NotifyShell_AssocChanged} SectionEnd !macro DeleteFileOrAskAbort path ClearErrors Delete "${path}" IfErrors 0 +3 MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP 'Unable to delete "${path}"!' IDRETRY -3 IDIGNORE +2 Abort "Aborted" !macroend Section -Uninstall !insertmacro DeleteFileOrAskAbort "$InstDir\MyApp.exe" Delete "$InstDir\Uninst.exe" RMDir "$InstDir" DeleteRegKey HKCU "${REGPATH_UNINSTSUBKEY}" ${UnpinShortcut} "$SMPrograms\${NAME}.lnk" Delete "$SMPrograms\${NAME}.lnk" SectionEnd