install-per-user.nsi 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. This example script installs a simple application for a single user.
  3. If multiple users on the same machine run this installer, each user
  4. will end up with a separate install that is not affected by
  5. update/removal operations performed by other users.
  6. Per-user installers should only write to HKCU and
  7. folders inside the users profile.
  8. */
  9. !define NAME "Per-user example"
  10. !define REGPATH_UNINSTSUBKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
  11. Name "${NAME}"
  12. OutFile "Install ${NAME}.exe"
  13. Unicode True
  14. RequestExecutionLevel User ; We don't need UAC elevation
  15. InstallDir "" ; Don't set a default $InstDir so we can detect /D= and InstallDirRegKey
  16. InstallDirRegKey HKCU "${REGPATH_UNINSTSUBKEY}" "UninstallString"
  17. !include LogicLib.nsh
  18. !include WinCore.nsh
  19. !include Integration.nsh
  20. Page Directory
  21. Page InstFiles
  22. Uninstpage UninstConfirm
  23. Uninstpage InstFiles
  24. Function .onInit
  25. SetShellVarContext Current
  26. ${If} $InstDir == "" ; No /D= nor InstallDirRegKey?
  27. GetKnownFolderPath $InstDir ${FOLDERID_UserProgramFiles} ; This folder only exists on Win7+
  28. StrCmp $InstDir "" 0 +2
  29. StrCpy $InstDir "$LocalAppData\Programs" ; Fallback directory
  30. StrCpy $InstDir "$InstDir\$(^Name)"
  31. ${EndIf}
  32. FunctionEnd
  33. Function un.onInit
  34. SetShellVarContext Current
  35. FunctionEnd
  36. Section "Program files (Required)"
  37. SectionIn Ro
  38. SetOutPath $InstDir
  39. WriteUninstaller "$InstDir\Uninst.exe"
  40. WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "DisplayName" "${NAME}"
  41. WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "DisplayIcon" "$InstDir\MyApp.exe,0"
  42. WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "UninstallString" '"$InstDir\Uninst.exe"'
  43. WriteRegStr HKCU "${REGPATH_UNINSTSUBKEY}" "QuietUninstallString" '"$InstDir\Uninst.exe" /S'
  44. WriteRegDWORD HKCU "${REGPATH_UNINSTSUBKEY}" "NoModify" 1
  45. WriteRegDWORD HKCU "${REGPATH_UNINSTSUBKEY}" "NoRepair" 1
  46. !tempfile APP
  47. !makensis '-v2 "-DOUTFILE=${APP}" "-DNAME=NSISPerUserAppExample" -DCOMPANY=Nullsoft "AppGen.nsi"' = 0
  48. File "/oname=$InstDir\MyApp.exe" "${APP}" ; Pretend that we have a real application to install
  49. !delfile "${APP}"
  50. SectionEnd
  51. Section "Start Menu shortcut"
  52. CreateShortcut /NoWorkingDir "$SMPrograms\${NAME}.lnk" "$InstDir\MyApp.exe"
  53. SectionEnd
  54. /*
  55. This Section registers a fictional .test-nullsoft file extension and the Nullsoft.Test ProgId.
  56. Proprietary file types are encouraged (by Microsoft) to use long file extensions and ProgIds that include the company name.
  57. When registering with "Open With" your executable should ideally have a somewhat unique name,
  58. otherwise there could be a naming collision with a different application (with the same name) installed on the same machine.
  59. REGISTER_DEFAULTPROGRAMS is not defined because proprietary file types do not typically use the Default Programs functionality.
  60. 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.
  61. 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).
  62. */
  63. !define ASSOC_EXT ".test-nullsoft"
  64. !define ASSOC_PROGID "Nullsoft.Test"
  65. !define ASSOC_VERB "MyApp"
  66. !define ASSOC_APPEXE "MyApp.exe"
  67. Section -ShellAssoc
  68. # Register file type
  69. WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\DefaultIcon" "" "$InstDir\${ASSOC_APPEXE},0"
  70. ;WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}" "" "Nullsoft Test App" [Optional]
  71. ;WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}" "MUIVerb" "@$InstDir\${ASSOC_APPEXE},-42" ; WinXP+ [Optional] Localizable verb display name
  72. WriteRegStr ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}\command" "" '"$InstDir\${ASSOC_APPEXE}" "%1"'
  73. WriteRegStr ShCtx "Software\Classes\${ASSOC_EXT}" "" "${ASSOC_PROGID}"
  74. # Register "Open With" [Optional]
  75. WriteRegNone ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithList" "${ASSOC_APPEXE}" ; Win2000+ [Optional]
  76. ;WriteRegNone ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithProgids" "${ASSOC_PROGID}" ; WinXP+ [Optional]
  77. WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\shell\open\command" "" '"$InstDir\${ASSOC_APPEXE}" "%1"'
  78. WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}" "FriendlyAppName" "Nullsoft Test App" ; [Optional]
  79. WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}" "ApplicationCompany" "Nullsoft" ; [Optional]
  80. WriteRegNone ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\SupportedTypes" "${ASSOC_EXT}" ; [Optional] Only allow "Open With" with specific extension(s) on WinXP+
  81. # Register "Default Programs" [Optional]
  82. !ifdef REGISTER_DEFAULTPROGRAMS
  83. WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities" "ApplicationDescription" "Shell association example test application"
  84. WriteRegStr ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities\FileAssociations" "${ASSOC_EXT}" "${ASSOC_PROGID}"
  85. WriteRegStr ShCtx "Software\RegisteredApplications" "Nullsoft Test App" "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities"
  86. !endif
  87. ${NotifyShell_AssocChanged}
  88. SectionEnd
  89. Section -un.ShellAssoc
  90. # Unregister file type
  91. ClearErrors
  92. DeleteRegKey ShCtx "Software\Classes\${ASSOC_PROGID}\shell\${ASSOC_VERB}"
  93. DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_PROGID}\shell"
  94. ${IfNot} ${Errors}
  95. DeleteRegKey ShCtx "Software\Classes\${ASSOC_PROGID}\DefaultIcon"
  96. ${EndIf}
  97. ReadRegStr $0 ShCtx "Software\Classes\${ASSOC_EXT}" ""
  98. DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_PROGID}"
  99. ${IfNot} ${Errors}
  100. ${AndIf} $0 == "${ASSOC_PROGID}"
  101. DeleteRegValue ShCtx "Software\Classes\${ASSOC_EXT}" ""
  102. DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}"
  103. ${EndIf}
  104. # Unregister "Open With"
  105. DeleteRegKey ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}"
  106. DeleteRegValue ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithList" "${ASSOC_APPEXE}"
  107. DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithList"
  108. DeleteRegValue ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithProgids" "${ASSOC_PROGID}"
  109. DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}\OpenWithProgids"
  110. DeleteRegKey /IfEmpty ShCtx "Software\Classes\${ASSOC_EXT}"
  111. # Unregister "Default Programs"
  112. !ifdef REGISTER_DEFAULTPROGRAMS
  113. DeleteRegValue ShCtx "Software\RegisteredApplications" "Nullsoft Test App"
  114. DeleteRegKey ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}\Capabilities"
  115. DeleteRegKey /IfEmpty ShCtx "Software\Classes\Applications\${ASSOC_APPEXE}"
  116. !endif
  117. # Attempt to clean up junk left behind by the Windows shell
  118. DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Search\JumplistData" "$InstDir\${ASSOC_APPEXE}"
  119. DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$InstDir\${ASSOC_APPEXE}.FriendlyAppName"
  120. DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$InstDir\${ASSOC_APPEXE}.ApplicationCompany"
  121. DeleteRegValue HKCU "Software\Microsoft\Windows\ShellNoRoam\MUICache" "$InstDir\${ASSOC_APPEXE}" ; WinXP
  122. DeleteRegValue HKCU "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store" "$InstDir\${ASSOC_APPEXE}"
  123. DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "${ASSOC_PROGID}_${ASSOC_EXT}"
  124. DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "Applications\${ASSOC_APPEXE}_${ASSOC_EXT}"
  125. DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}\OpenWithProgids" "${ASSOC_PROGID}"
  126. DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}\OpenWithProgids"
  127. DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}\OpenWithList"
  128. DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${ASSOC_EXT}"
  129. ;DeleteRegKey HKCU "Software\Microsoft\Windows\Roaming\OpenWith\FileExts\${ASSOC_EXT}"
  130. ;DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs\${ASSOC_EXT}"
  131. ${NotifyShell_AssocChanged}
  132. SectionEnd
  133. !macro DeleteFileOrAskAbort path
  134. ClearErrors
  135. Delete "${path}"
  136. IfErrors 0 +3
  137. MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP 'Unable to delete "${path}"!' IDRETRY -3 IDIGNORE +2
  138. Abort "Aborted"
  139. !macroend
  140. Section -Uninstall
  141. !insertmacro DeleteFileOrAskAbort "$InstDir\MyApp.exe"
  142. Delete "$InstDir\Uninst.exe"
  143. RMDir "$InstDir"
  144. DeleteRegKey HKCU "${REGPATH_UNINSTSUBKEY}"
  145. ${UnpinShortcut} "$SMPrograms\${NAME}.lnk"
  146. Delete "$SMPrograms\${NAME}.lnk"
  147. SectionEnd