我可以让 NSIS 制作一个处理本地部署和系统部署的安装程序吗?
Can I get NSIS to make a single installer that handles local deployment and system deployment?
Chrome 有一个安装程序,可用于在系统范围内安装,或安装到用户的主目录(如果用户不是管理员)。当您在公司环境中部署时,这很有用,您仍然希望允许潜在用户安装,即使他们不一定具有安装权限。
NSIS 可以用来创建这样的安装程序吗?
事实证明可以。重要的部分是:
RequestExecutionLevel highest
:这可确保安装程序获得用户帐户可用的最高权限。也就是说,如果他们在管理员组中,安装程序将要求提升权限。
- 正在确定用户是否为管理员。这是使用 UserInfo 插件实现的。这很简单。
SetShellVarContext all|current
:这决定了特殊注册表根键的值SHCTX
。对于 all
,它与 HKLM
(系统范围)的含义相同,对于 current
,它的结果是 HKCU
。 SetShellVarContext
还会影响 $SMPROGRAMS
的值是指系统范围的开始菜单还是仅指用户的层次结构。
这是一个安装程序的框架,可以在系统范围内或本地部署,具体取决于用户帐户的权限。它使用 C:\Windows\write.exe 作为其有效载荷,并可选择安装开始菜单项和桌面快捷方式。它还在注册表中放置了对卸载程序的引用,以便它显示在 Add/Remove 程序对话框中。我使用 NSIS 3.0(测试版)来构建它,但我没有看到任何明显的原因为什么它不能与最近的 2.x.
一起使用
!include "MUI2.nsh"
!define PRODUCT_NAME "DummyProduct"
!define VERSION "0.0.1"
Var INSTDIR_BASE
Name "${PRODUCT_NAME}"
OutFile "${PRODUCT_NAME} Installer.exe"
InstallDir ""
; Take the highest execution level available
; This means that if it's possible to, we become an administrator
RequestExecutionLevel highest
!macro ONINIT un
Function ${un}.onInit
; The value of SetShellVarContext detetmines whether SHCTX is HKLM or HKCU
; and whether SMPROGRAMS refers to all users or just the current user
UserInfo::GetAccountType
Pop [=10=]
${If} [=10=] == "Admin"
; If we're an admin, default to installing to C:\Program Files
SetShellVarContext all
StrCpy $INSTDIR_BASE "$PROGRAMFILES64"
${Else}
; If we're just a user, default to installing to ~\AppData\Local
SetShellVarContext current
StrCpy $INSTDIR_BASE "$LOCALAPPDATA"
${EndIf}
${If} $INSTDIR == ""
; This only happens in the installer, because the uninstaller already knows INSTDIR
ReadRegStr [=10=] SHCTX "Software${PRODUCT_NAME}" ""
${If} [=10=] != ""
; If we're already installed, use the existing directory
StrCpy $INSTDIR "[=10=]"
${Else}
StrCpy $INSTDIR "$INSTDIR_BASE${PRODUCT_NAME}"
${Endif}
${Endif}
FunctionEnd
!macroend
; Define the function twice, once for the installer and again for the uninstaller
!insertmacro ONINIT ""
!insertmacro ONINIT "un"
!define MUI_ABORTWARNING
!define MUI_COMPONENTSPAGE_NODESC
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
Var STARTMENU_FOLDER
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software${PRODUCT_NAME}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
!insertmacro MUI_PAGE_STARTMENU ${PRODUCT_NAME} $STARTMENU_FOLDER
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section "-Main Component"
SetOutPath "$INSTDIR"
File "C:\Windows\write.exe"
WriteRegStr SHCTX "Software${PRODUCT_NAME}" "" $INSTDIR
; These registry entries are necessary for the program to show up in the Add/Remove programs dialog
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}"
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "NoModify" 1
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "NoRepair" 1
WriteUninstaller "$INSTDIR\Uninstall.exe"
!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}
CreateDirectory "$SMPROGRAMS$STARTMENU_FOLDER\"
CreateShortCut "$SMPROGRAMS$STARTMENU_FOLDER${PRODUCT_NAME}.lnk" "$INSTDIR\write.exe"
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
Section "Desktop shortcut"
CreateShortCut "$DESKTOP${PRODUCT_NAME}.lnk" "$INSTDIR\write.exe"
SectionEnd
Section "Uninstall"
Delete "$INSTDIR\write.exe"
Delete "$INSTDIR\Uninstall.exe"
RMDir /r "$INSTDIR"
!insertmacro MUI_STARTMENU_GETFOLDER ${PRODUCT_NAME} $STARTMENU_FOLDER
Delete "$SMPROGRAMS$STARTMENU_FOLDER${PRODUCT_NAME}.lnk"
RMDir /r "$SMPROGRAMS$STARTMENU_FOLDER"
Delete "$DESKTOP${PRODUCT_NAME}.lnk"
DeleteRegKey /ifempty SHCTX "Software${PRODUCT_NAME}"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}"
SectionEnd
Chrome 有一个安装程序,可用于在系统范围内安装,或安装到用户的主目录(如果用户不是管理员)。当您在公司环境中部署时,这很有用,您仍然希望允许潜在用户安装,即使他们不一定具有安装权限。
NSIS 可以用来创建这样的安装程序吗?
事实证明可以。重要的部分是:
RequestExecutionLevel highest
:这可确保安装程序获得用户帐户可用的最高权限。也就是说,如果他们在管理员组中,安装程序将要求提升权限。- 正在确定用户是否为管理员。这是使用 UserInfo 插件实现的。这很简单。
SetShellVarContext all|current
:这决定了特殊注册表根键的值SHCTX
。对于all
,它与HKLM
(系统范围)的含义相同,对于current
,它的结果是HKCU
。SetShellVarContext
还会影响$SMPROGRAMS
的值是指系统范围的开始菜单还是仅指用户的层次结构。
这是一个安装程序的框架,可以在系统范围内或本地部署,具体取决于用户帐户的权限。它使用 C:\Windows\write.exe 作为其有效载荷,并可选择安装开始菜单项和桌面快捷方式。它还在注册表中放置了对卸载程序的引用,以便它显示在 Add/Remove 程序对话框中。我使用 NSIS 3.0(测试版)来构建它,但我没有看到任何明显的原因为什么它不能与最近的 2.x.
一起使用!include "MUI2.nsh"
!define PRODUCT_NAME "DummyProduct"
!define VERSION "0.0.1"
Var INSTDIR_BASE
Name "${PRODUCT_NAME}"
OutFile "${PRODUCT_NAME} Installer.exe"
InstallDir ""
; Take the highest execution level available
; This means that if it's possible to, we become an administrator
RequestExecutionLevel highest
!macro ONINIT un
Function ${un}.onInit
; The value of SetShellVarContext detetmines whether SHCTX is HKLM or HKCU
; and whether SMPROGRAMS refers to all users or just the current user
UserInfo::GetAccountType
Pop [=10=]
${If} [=10=] == "Admin"
; If we're an admin, default to installing to C:\Program Files
SetShellVarContext all
StrCpy $INSTDIR_BASE "$PROGRAMFILES64"
${Else}
; If we're just a user, default to installing to ~\AppData\Local
SetShellVarContext current
StrCpy $INSTDIR_BASE "$LOCALAPPDATA"
${EndIf}
${If} $INSTDIR == ""
; This only happens in the installer, because the uninstaller already knows INSTDIR
ReadRegStr [=10=] SHCTX "Software${PRODUCT_NAME}" ""
${If} [=10=] != ""
; If we're already installed, use the existing directory
StrCpy $INSTDIR "[=10=]"
${Else}
StrCpy $INSTDIR "$INSTDIR_BASE${PRODUCT_NAME}"
${Endif}
${Endif}
FunctionEnd
!macroend
; Define the function twice, once for the installer and again for the uninstaller
!insertmacro ONINIT ""
!insertmacro ONINIT "un"
!define MUI_ABORTWARNING
!define MUI_COMPONENTSPAGE_NODESC
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
Var STARTMENU_FOLDER
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software${PRODUCT_NAME}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
!insertmacro MUI_PAGE_STARTMENU ${PRODUCT_NAME} $STARTMENU_FOLDER
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Section "-Main Component"
SetOutPath "$INSTDIR"
File "C:\Windows\write.exe"
WriteRegStr SHCTX "Software${PRODUCT_NAME}" "" $INSTDIR
; These registry entries are necessary for the program to show up in the Add/Remove programs dialog
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}"
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "NoModify" 1
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}" "NoRepair" 1
WriteUninstaller "$INSTDIR\Uninstall.exe"
!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}
CreateDirectory "$SMPROGRAMS$STARTMENU_FOLDER\"
CreateShortCut "$SMPROGRAMS$STARTMENU_FOLDER${PRODUCT_NAME}.lnk" "$INSTDIR\write.exe"
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
Section "Desktop shortcut"
CreateShortCut "$DESKTOP${PRODUCT_NAME}.lnk" "$INSTDIR\write.exe"
SectionEnd
Section "Uninstall"
Delete "$INSTDIR\write.exe"
Delete "$INSTDIR\Uninstall.exe"
RMDir /r "$INSTDIR"
!insertmacro MUI_STARTMENU_GETFOLDER ${PRODUCT_NAME} $STARTMENU_FOLDER
Delete "$SMPROGRAMS$STARTMENU_FOLDER${PRODUCT_NAME}.lnk"
RMDir /r "$SMPROGRAMS$STARTMENU_FOLDER"
Delete "$DESKTOP${PRODUCT_NAME}.lnk"
DeleteRegKey /ifempty SHCTX "Software${PRODUCT_NAME}"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall${PRODUCT_NAME}"
SectionEnd