根据 NSIS 中的 CurrentUser/AllUsers 安装模式自定义 INSTDIR
Customize INSTDIR according to CurrentUser/AllUsers install modes in NSIS
根据MultiUser.nsh
的宏,$INSTDIR
会根据$MultiUser.InstallMode
的值设置为以下路径之一:
- 当前用户:
"$LOCALAPPDATA${MULTIUSER_INSTALLMODE_INSTDIR}"
- 所有用户:
"$PROGRAMFILES${MULTIUSER_INSTALLMODE_INSTDIR}"
基本上宏将 $MULTIUSER_INSTALLMODE_INSTDIR
附加到 $LOCALAPPDATA
或 $PROGRAMFILES
并将其用作默认安装路径。
我需要的只是 CurrentUser 安装模式略有不同的路径,即:
"$LOCALAPPDATA\Programs${MULTIUSER_INSTALLMODE_INSTDIR}"
我怎样才能做到这一点?
鉴于用户有机会选择安装模式,因此必须在做出此选择后设置默认 $INSTDIR
值。
您可以使用MULTIUSER_INSTALLMODE_FUNCTION回调函数定义进行更改:
Name "MultiUser test"
!define MULTIUSER_INSTALLMODE_INSTDIR "$(^Name)"
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_INSTALLMODE_FUNCTION onMultiUserModeChanged
!define MULTIUSER_MUI
!include MultiUser.nsh
!include MUI2.nsh
!include LogicLib.nsh
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Function .onInit
!insertmacro MULTIUSER_INIT
FunctionEnd
Function un.onInit
!insertmacro MULTIUSER_UNINIT
FunctionEnd
Function onMultiUserModeChanged
${If} $MultiUser.InstallMode == "CurrentUser"
StrCpy $InstDir "$LocalAppdata\Programs${MULTIUSER_INSTALLMODE_INSTDIR}"
${EndIf}
FunctionEnd
Section
MessageBox MB_OK $InstDir
Quit ; This is just a demo
SetOutPath $InstDir
WriteUninstaller "$InstDir\Uninst.exe"
SectionEnd
Section Uninstall
Delete "$InstDir\Uninst.exe"
RMDir $InstDir
SectionEnd
或者更好,如果可用,请使用 UserProgramFiles 已知文件夹:
!macro GetUserProgramFiles outvar
!define /IfNDef KF_FLAG_CREATE 0x00008000
!define /IfNDef FOLDERID_UserProgramFiles {5CD7AEE2-2219-4A67-B85D-6C9CE15660CB}
System::Store S
System::Call 'SHELL32::SHGetKnownFolderPath(g "${FOLDERID_UserProgramFiles}", i ${KF_FLAG_CREATE}, p 0, *p .r2)i.r1' ; This will only work on Win7+
${If} == 0
System::Call '*(&w${NSIS_MAX_STRLEN} .s)'
System::Call 'OLE32::CoTaskMemFree(p r2)'
${Else}
Push "$LocalAppData\Programs"
${EndIf}
System::Store L
Pop ${outvar}
!macroend
Function onMultiUserModeChanged
${If} $MultiUser.InstallMode == "CurrentUser"
!insertmacro GetUserProgramFiles $InstDir
StrCpy $InstDir "$InstDir${MULTIUSER_INSTALLMODE_INSTDIR}"
${EndIf}
FunctionEnd
根据MultiUser.nsh
的宏,$INSTDIR
会根据$MultiUser.InstallMode
的值设置为以下路径之一:
- 当前用户:
"$LOCALAPPDATA${MULTIUSER_INSTALLMODE_INSTDIR}"
- 所有用户:
"$PROGRAMFILES${MULTIUSER_INSTALLMODE_INSTDIR}"
基本上宏将 $MULTIUSER_INSTALLMODE_INSTDIR
附加到 $LOCALAPPDATA
或 $PROGRAMFILES
并将其用作默认安装路径。
我需要的只是 CurrentUser 安装模式略有不同的路径,即:
"$LOCALAPPDATA\Programs${MULTIUSER_INSTALLMODE_INSTDIR}"
我怎样才能做到这一点?
鉴于用户有机会选择安装模式,因此必须在做出此选择后设置默认 $INSTDIR
值。
您可以使用MULTIUSER_INSTALLMODE_FUNCTION回调函数定义进行更改:
Name "MultiUser test"
!define MULTIUSER_INSTALLMODE_INSTDIR "$(^Name)"
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_INSTALLMODE_FUNCTION onMultiUserModeChanged
!define MULTIUSER_MUI
!include MultiUser.nsh
!include MUI2.nsh
!include LogicLib.nsh
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Function .onInit
!insertmacro MULTIUSER_INIT
FunctionEnd
Function un.onInit
!insertmacro MULTIUSER_UNINIT
FunctionEnd
Function onMultiUserModeChanged
${If} $MultiUser.InstallMode == "CurrentUser"
StrCpy $InstDir "$LocalAppdata\Programs${MULTIUSER_INSTALLMODE_INSTDIR}"
${EndIf}
FunctionEnd
Section
MessageBox MB_OK $InstDir
Quit ; This is just a demo
SetOutPath $InstDir
WriteUninstaller "$InstDir\Uninst.exe"
SectionEnd
Section Uninstall
Delete "$InstDir\Uninst.exe"
RMDir $InstDir
SectionEnd
或者更好,如果可用,请使用 UserProgramFiles 已知文件夹:
!macro GetUserProgramFiles outvar
!define /IfNDef KF_FLAG_CREATE 0x00008000
!define /IfNDef FOLDERID_UserProgramFiles {5CD7AEE2-2219-4A67-B85D-6C9CE15660CB}
System::Store S
System::Call 'SHELL32::SHGetKnownFolderPath(g "${FOLDERID_UserProgramFiles}", i ${KF_FLAG_CREATE}, p 0, *p .r2)i.r1' ; This will only work on Win7+
${If} == 0
System::Call '*(&w${NSIS_MAX_STRLEN} .s)'
System::Call 'OLE32::CoTaskMemFree(p r2)'
${Else}
Push "$LocalAppData\Programs"
${EndIf}
System::Store L
Pop ${outvar}
!macroend
Function onMultiUserModeChanged
${If} $MultiUser.InstallMode == "CurrentUser"
!insertmacro GetUserProgramFiles $InstDir
StrCpy $InstDir "$InstDir${MULTIUSER_INSTALLMODE_INSTDIR}"
${EndIf}
FunctionEnd