!include "StrFunc.nsh" !include "WordFunc.nsh" ${StrRep} ${StrStr} !include "LogicLib.nsh" !include "nsDialogs.nsh" !include "common.nsh" !include "x64.nsh" !include "MUI.nsh" !include "WinVer.nsh" !include "commonfunc.nsh" !insertmacro MUI_LANGUAGE "SimpChinese" VIProductVersion "${PRODUCT_VERSION}" VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}" VIAddVersionKey "ProductName" "${PRODUCT_NAME}" VIAddVersionKey "CompanyName" "${PRODUCT_PUBLISHER}" VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}" VIAddVersionKey "InternalName" "${EXE_NAME}" VIAddVersionKey "FileDescription" "${PRODUCT_NAME}" VIAddVersionKey "LegalCopyright" "${PRODUCT_LEGAL}" !define INSTALL_PAGE_CONFIG 0 ;!define INSTALL_PAGE_LICENSE 1 !define INSTALL_PAGE_PROCESSING 1 !define INSTALL_PAGE_FINISH 2 !define INSTALL_PAGE_UNISTCONFIG 3 !define INSTALL_PAGE_UNISTPROCESSING 4 !define INSTALL_PAGE_UNISTFINISH 5 Page custom DUIPage UninstPage custom un.DUIPage Var hInstallDlg Var hInstallSubDlg Var sCmdFlag Var sCmdSetupPath Var sSetupPath Var sReserveData Var InstallState Var UnInstallValue Var temp11 Var temp12 Var OLD_VER Var step ;在安装程序运行前的回调函数前实现 Function .onInit ${IfNot} ${AtLeastWin10} MessageBox MB_OK|MB_USERICON '本程序只能安装在windows-10(64位)系统上' Abort ${EndIf} ReadRegStr $OLD_VER HKLM "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_PATHNAME}" "DisplayVersion" ${IF} $OLD_VER != "" ${VersionCompare} $OLD_VER ${PRODUCT_VERSION} $R0 ${If} $R0 == "0" MessageBox MB_OK|MB_USERICON '${PRODUCT_PATHNAME},版本 $OLD_VER 已安装在计算机中。如需重新安装,请卸载已有的安装' Quit ${EndIf} ${If} $R0 == "1" MessageBox MB_OK|MB_USERICON '${PRODUCT_PATHNAME},版本 $OLD_VER 已安装在计算机中。如需重新安装,请卸载已有的安装' ;MessageBox MB_OK|MB_USERICON '${PRODUCT_PATHNAME},您安装的版本是 ${PRODUCT_VERSION} 小于版本 $OLD_VER ' Quit ${EndIf} ${If} $R0 == "2" MessageBox MB_OK|MB_USERICON '${PRODUCT_PATHNAME},版本 $OLD_VER 已安装在计算机中。如需重新安装,请卸载已有的安装' ;MessageBox MB_OK|MB_USERICON '${PRODUCT_PATHNAME},您安装的版本是 ${PRODUCT_VERSION} 大于版本 $OLD_VER ' Quit ${EndIf} ${EndIf} FunctionEnd Function DUIPage StrCpy $InstallState "0" InitPluginsDir SetOutPath "$PLUGINSDIR" File "${INSTALL_LICENCE_FILENAME}" File "${INSTALL_RES_PATH}" File /oname=logo.ico "${INSTALL_ICO}" # nsNiuniuSkin::InitSkinPage "$PLUGINSDIR\" "${INSTALL_LICENCE_FILENAME}" Pop $hInstallDlg Call GenerateSetupAddress nsNiuniuSkin::SetControlAttribute $hInstallDlg "editDir" "text" "$INSTDIR\" Call OnRichEditTextChange nsNiuniuSkin::SetWindowTile $hInstallDlg "${PRODUCT_NAME}安装程序" nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_CONFIG} nsNiuniuSkin::SetControlAttribute $hInstallDlg "licensename" "text" "《四维深时本地版用户许可协议》" Call BindUIControls nsNiuniuSkin::ShowPage 0 FunctionEnd Function un.DUIPage StrCpy $InstallState "0" InitPluginsDir SetOutPath "$PLUGINSDIR" File "${INSTALL_RES_PATH}" File /oname=logo.ico "${UNINSTALL_ICO}" nsNiuniuSkin::InitSkinPage "$PLUGINSDIR\" "" Pop $hInstallDlg nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_UNISTCONFIG} nsNiuniuSkin::SetWindowTile $hInstallDlg "${PRODUCT_NAME}卸载程序" nsNiuniuSkin::SetWindowSize $hInstallDlg 480 390s Call un.BindUnInstUIControls nsNiuniuSkin::SetControlAttribute $hInstallDlg "chkAutoRun" "selected" "true" nsNiuniuSkin::ShowPage 0 FunctionEnd Function un.BindUnInstUIControls GetFunctionAddress $0 un.ExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnUninstalled" $0 GetFunctionAddress $0 un.onUninstall nsNiuniuSkin::BindCallBack $hInstallDlg "btnUnInstall" $0 GetFunctionAddress $0 un.ExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnClose" $0 FunctionEnd Function BindUIControls GetFunctionAddress $0 OnExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnLicenseClose" $0 GetFunctionAddress $0 OnBtnMin nsNiuniuSkin::BindCallBack $hInstallDlg "btnLicenseMin" $0 GetFunctionAddress $0 OnBtnLicenseClick nsNiuniuSkin::BindCallBack $hInstallDlg "btnAgreement" $0 GetFunctionAddress $0 OnExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnDirClose" $0 GetFunctionAddress $0 OnExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnLicenseCancel" $0 GetFunctionAddress $0 OnBtnMin nsNiuniuSkin::BindCallBack $hInstallDlg "btnDirMin" $0 GetFunctionAddress $0 OnBtnSelectDir nsNiuniuSkin::BindCallBack $hInstallDlg "btnSelectDir" $0 GetFunctionAddress $0 OnBtnDirPre nsNiuniuSkin::BindCallBack $hInstallDlg "btnDirPre" $0 GetFunctionAddress $0 OnBtnShowConfig nsNiuniuSkin::BindCallBack $hInstallDlg "btnAgree" $0 GetFunctionAddress $0 OnBtnCancel nsNiuniuSkin::BindCallBack $hInstallDlg "btnDirCancel" $0 GetFunctionAddress $0 OnBtnInstall nsNiuniuSkin::BindCallBack $hInstallDlg "btnInstall" $0 GetFunctionAddress $0 OnExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnDetailClose" $0 GetFunctionAddress $0 OnBtnMin nsNiuniuSkin::BindCallBack $hInstallDlg "btnDetailMin" $0 GetFunctionAddress $0 OnFinished nsNiuniuSkin::BindCallBack $hInstallDlg "btnRun" $0 GetFunctionAddress $0 OnBtnMin nsNiuniuSkin::BindCallBack $hInstallDlg "btnFinishedMin" $0 GetFunctionAddress $0 OnExitDUISetup nsNiuniuSkin::BindCallBack $hInstallDlg "btnClose" $0 GetFunctionAddress $0 OnCheckLicenseClick nsNiuniuSkin::BindCallBack $hInstallDlg "chkAgree" $0 GetFunctionAddress $0 OnBtnShowMore nsNiuniuSkin::BindCallBack $hInstallDlg "btnShowMore" $0 GetFunctionAddress $0 OnBtnHideMore nsNiuniuSkin::BindCallBack $hInstallDlg "btnHideMore" $0 GetFunctionAddress $0 OnSysCommandCloseEvent nsNiuniuSkin::BindCallBack $hInstallDlg "syscommandclose" $0 GetFunctionAddress $0 OnRichEditTextChange nsNiuniuSkin::BindCallBack $hInstallDlg "editDir" $0 FunctionEnd Function OnRichEditTextChange nsNiuniuSkin::GetControlAttribute $hInstallDlg "editDir" "text" Pop $0 StrCpy $INSTDIR "$0" Call onVerifyInstDir Pop $0 ${If} $0 == 1 nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "text" "不能包含中文路径" nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "textcolor" "#ffff0000" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnInstall" "enabled" "false" goto TextChangeAbort ${EndIf} Call IsSetupPathIlleagal ${If} $R5 == "0" nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "text" "路径非法" nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "textcolor" "#ffff0000" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnInstall" "enabled" "false" goto TextChangeAbort ${EndIf} nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "textcolor" "#FF999999" ${If} $R0 > 1024 IntOp $R1 $R0 % 1024 IntOp $R0 $R0 / 1024; nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "text" "剩余空间:$R0.$R1GB" ${Else} nsNiuniuSkin::SetControlAttribute $hInstallDlg "local_space" "text" "剩余空间:$R0.$R1MB" ${endif} nsNiuniuSkin::GetControlAttribute $hInstallDlg "chkAgree" "selected" Pop $0 ${If} $0 == "1" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnInstall" "enabled" "true" ${Else} nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnInstall" "enabled" "false" ${EndIf} TextChangeAbort: FunctionEnd Function OnCheckLicenseClick nsNiuniuSkin::GetControlAttribute $hInstallDlg "chkAgree" "selected" Pop $0 ${If} $0 == "0" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnInstall" "enabled" "true" ${Else} nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnInstall" "enabled" "false" ${EndIf} FunctionEnd Function OnBtnLicenseClick ;nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_LICENSE} nsNiuniuSkin::SetControlAttribute $hInstallDlg "licenseshow" "visible" "true" nsNiuniuSkin::GetControlAttribute $hInstallDlg "moreconfiginfo" "visible" Pop $0 ${If} $0 = 0 ;pos="10,35,560,405" nsNiuniuSkin::SetControlAttribute $hInstallDlg "licenseshow" "pos" "5,35,475,385" nsNiuniuSkin::SetControlAttribute $hInstallDlg "editLicense" "height" "270" ${Else} nsNiuniuSkin::SetControlAttribute $hInstallDlg "licenseshow" "pos" "5,35,475,495" nsNiuniuSkin::SetControlAttribute $hInstallDlg "editLicense" "height" "375" ${EndIf} FunctionEnd Section "silentInstallSec" SEC01 #MessageBox MB_OK|MB_ICONINFORMATION "Test silent install. you can add your silent install code here." SectionEnd Function ShowMsgBox nsNiuniuSkin::InitSkinSubPage "msgBox.xml" "btnOK" "btnCancel,btnClose" Pop $hInstallSubDlg nsNiuniuSkin::SetControlAttribute $hInstallSubDlg "lblTitle" "text" "提示" nsNiuniuSkin::SetControlAttribute $hInstallSubDlg "lblMsg" "text" "$R8" ${If} "$R7" == "1" nsNiuniuSkin::SetControlAttribute $hInstallSubDlg "hlCancel" "visible" "true" ${EndIf} nsNiuniuSkin::ShowSkinSubPage 0 FunctionEnd Function OnBtnInstall nsNiuniuSkin::GetControlAttribute $hInstallDlg "chkAgree" "selected" Pop $0 StrCpy $0 "1" StrCmp $0 "0" InstallAbort 0 nsProcess::_FindProcess "${EXE_NAME}" Pop $R0 ${If} $R0 == 0 StrCpy $R8 "${PRODUCT_NAME} 正在运行,请退出后重试!" StrCpy $R7 "0" Call ShowMsgBox goto InstallAbort ${EndIf} nsNiuniuSkin::GetControlAttribute $hInstallDlg "editDir" "text" Pop $0 StrCmp $0 "" InstallAbort 0 Call AdjustInstallPath StrCpy $sSetupPath "$INSTDIR" Call IsSetupPathIlleagal ${If} $R5 == "0" StrCpy $R8 "路径非法,请使用正确的路径安装!" StrCpy $R7 "0" Call ShowMsgBox goto InstallAbort ${EndIf} ${If} $R5 == "-1" StrCpy $R8 "目标磁盘空间不足,请使用其他的磁盘安装!" StrCpy $R7 "0" Call ShowMsgBox goto InstallAbort ${EndIf} nsNiuniuSkin::SetWindowSize $hInstallDlg 480 390 nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnClose" "enabled" "false" nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_PROCESSING} nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrProgress" "min" "0" nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrProgress" "max" "100" #Call BakFiles GetFunctionAddress $0 ExtractFunc BgWorker::CallAndWait nsNiuniuSkin::GetControlAttribute $hInstallDlg "chkShotcut" "selected" #Pop $R0 # ${If} $R0 == "1" # SetShellVarContext all # CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${EXE_NAME}" # SetShellVarContext current # ${EndIf} SetShellVarContext all CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${EXE_NAME}" SetShellVarContext current Call CreateAppShortcut Call CreateUninstall nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnClose" "enabled" "true" StrCpy $InstallState "1" #Call OnFinished Call OnEnvInstall nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_FINISH} InstallAbort: FunctionEnd Function ExtractCallback Pop $1 Pop $2 System::Int64Op $1 * 100 Pop $3 System::Int64Op $3 / $2 Pop $0 nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrProgress" "value" "$0" nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_pos" "text" "$0%" ${If} $1 == $2 nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrProgress" "value" "100" nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_pos" "text" "100%" ${EndIf} FunctionEnd Function OnSysCommandCloseEvent Call OnExitDUISetup FunctionEnd Function OnExitDUISetup ${If} $InstallState == "0" StrCpy $R8 "安装尚未完成,您确定退出安装么?" StrCpy $R7 "1" Call ShowMsgBox pop $0 ${If} $0 == 0 goto endfun ${EndIf} ${EndIf} nsNiuniuSkin::ExitDUISetup endfun: FunctionEnd Function OnBtnMin SendMessage $hInstallDlg ${WM_SYSCOMMAND} 0xF020 0 FunctionEnd Function OnBtnCancel nsNiuniuSkin::ExitDUISetup FunctionEnd Function OnEnvInstall #2、nsExec::Exec "$INSTDIR\nsis.bat" nsExec::Exec "$INSTDIR\env_install.bat" FunctionEnd Function OnFinished #MessageBox MB_YESNO|MB_ICONQUESTION "需要重启系统才能完成安装" IDNO +2 #Reboot #Exec "$INSTDIR\${EXE_NAME}" Call OnExitDUISetup FunctionEnd Function OnBtnSelectDir nsNiuniuSkin::SelectInstallDirEx $hInstallDlg "请选择安装路径" Pop $0 ${Unless} "$0" == "" nsNiuniuSkin::SetControlAttribute $hInstallDlg "editDir" "text" $0 ${EndUnless} FunctionEnd Function StepHeightSizeAsc ${ForEach} $R0 390 500 + 10 nsNiuniuSkin::SetWindowSize $hInstallDlg 480 $R0 Sleep 5 ${Next} FunctionEnd Function StepHeightSizeDsc ${ForEach} $R0 480 390 - 10 nsNiuniuSkin::SetWindowSize $hInstallDlg 480 $R0 Sleep 5 ${Next} FunctionEnd Function OnBtnShowMore nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnShowMore" "enabled" "false" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnHideMore" "enabled" "false" nsNiuniuSkin::SetControlAttribute $hInstallDlg "moreconfiginfo" "visible" "true" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnHideMore" "visible" "true" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnShowMore" "visible" "false" GetFunctionAddress $0 StepHeightSizeAsc BgWorker::CallAndWait nsNiuniuSkin::SetWindowSize $hInstallDlg 480 500 nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnShowMore" "enabled" "true" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnHideMore" "enabled" "true" FunctionEnd Function OnBtnHideMore nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnShowMore" "enabled" "false" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnHideMore" "enabled" "false" nsNiuniuSkin::SetControlAttribute $hInstallDlg "moreconfiginfo" "visible" "false" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnHideMore" "visible" "false" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnShowMore" "visible" "true" GetFunctionAddress $0 StepHeightSizeDsc BgWorker::CallAndWait nsNiuniuSkin::SetWindowSize $hInstallDlg 480 390 nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnShowMore" "enabled" "true" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnHideMore" "enabled" "true" FunctionEnd Function OnBtnShowConfig ;nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_CONFIG} nsNiuniuSkin::SetControlAttribute $hInstallDlg "licenseshow" "visible" "false" FunctionEnd Function OnBtnDirPre StrCpy $R8 "安装尚未完成,您确定退出安装么?" StrCpy $R7 "0" Call ShowMsgBox ;nsNiuniuSkin::PrePage "wizardTab" FunctionEnd Function un.ShowMsgBox nsNiuniuSkin::InitSkinSubPage "msgBox.xml" "btnOK" "btnCancel,btnClose" Pop $hInstallSubDlg nsNiuniuSkin::SetControlAttribute $hInstallSubDlg "lblTitle" "text" "提示" nsNiuniuSkin::SetControlAttribute $hInstallSubDlg "lblMsg" "text" "$R8" ${If} "$R7" == "1" nsNiuniuSkin::SetControlAttribute $hInstallSubDlg "hlCancel" "visible" "true" ${EndIf} nsNiuniuSkin::ShowSkinSubPage 0 FunctionEnd Function un.ExitDUISetup nsNiuniuSkin::ExitDUISetup FunctionEnd Section "un.silentInstallSec" SEC02 #MessageBox MB_OK|MB_ICONINFORMATION "Test silent install. you can add your silent uninstall code here." SectionEnd Function un.onUninstall nsProcess::_FindProcess "${EXE_NAME}" Pop $R0 ${If} $R0 == 0 StrCpy $R8 "${PRODUCT_NAME} 正在运行,请退出后重试!" StrCpy $R7 "0" Call un.ShowMsgBox goto InstallAbort ${EndIf} nsNiuniuSkin::GetControlAttribute $hInstallDlg "chkbox_userdata" "selected" Pop $0 StrCpy $sReserveData $0 ${If} $sReserveData == 1 CreateDirectory $INSTDIR\USER_DATA ${EndIf} nsExec::Exec "$INSTDIR\uninstall.bat" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnClose" "enabled" "false" nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_UNISTPROCESSING} nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrUnInstProgress" "min" "0" nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrUnInstProgress" "max" "100" IntOp $UnInstallValue 0 + 1 Call un.DeleteShotcutAndInstallInfo IntOp $UnInstallValue $UnInstallValue + 8 GetFunctionAddress $0 un.RemoveFiles BgWorker::CallAndWait InstallAbort: FunctionEnd Function un.RemoveFiles ${Locate} "$INSTDIR" "/G=0 /M=*.*" "un.onDeleteFileFound" StrCpy $InstallState "1" nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnClose" "enabled" "true" nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrUnInstProgress" "value" "100" nsNiuniuSkin::ShowPageItem $hInstallDlg "wizardTab" ${INSTALL_PAGE_UNISTFINISH} FunctionEnd Function un.onDeleteFileFound ; $R9 "path\name" ; $R8 "path" ; $R7 "name" ; $R6 "size" ($R6 = "" if directory, $R6 = "0" if file with /S=) ${If} $sReserveData == 0 Delete "$R9" RMDir /r "$R9" RMDir "$R9" ${EndIf} ${If} $sReserveData == 1 RMDir /r /REBOOTOK "$R8\bin" RMDir /r /REBOOTOK "$R8\4DKK_CGAII" RMDir /r /REBOOTOK "$R8\mongodb" RMDir /r /REBOOTOK "$R8\mysql" RMDir /r /REBOOTOK "$R8\redis" RMDir /r /REBOOTOK "$R8\jdk1.8" Delete "$R8\reInstall.bat" ${EndIf} IntOp $UnInstallValue $UnInstallValue + 2 ${If} $UnInstallValue > 100 IntOp $UnInstallValue 100 + 0 nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrUnInstProgress" "value" "100" ${Else} nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrUnInstProgress" "value" "$UnInstallValue" nsNiuniuSkin::SetControlAttribute $hInstallDlg "un_progress_pos" "text" "$UnInstallValue%" #Sleep 100 ${EndIf} undelete: Push "LocateNext" FunctionEnd # # 以 Unicode 字符串的方式进行判断 (与 NSIS 是 ANSI/Unicode 无关) # 但建议 Unicode 版本优先使用此函数。 # Function PathIsDBCS_W Exch $R0 Push $R1 Push $R2 Push $R3 System::Call "*(&w${NSIS_MAX_STRLEN}R0)p.R1" StrCpy $R0 0 StrCpy $R2 $R1 lbl_loop: # Unicode 版取 2 个字节长度的字符,字符串遇到 0 字符表示结束了。 System::Call "*$R2(&i2.R3)" IntCmp $R3 0 lbl_done # Unicode 字符直接判断字符值,大于 128 的我们就视为非英文字符。 IntCmp $R3 128 0 lbl_skip IntOp $R0 $R0 ! Goto lbl_done lbl_skip: # 如果用 NSIS 3.x 这里可以用 IntPtrOp 代替。 IntOp $R2 $R2 + 2 Goto lbl_loop lbl_done: System::Free $R1 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd # # 以 ANSI 字符串的方式进行判断 (与 NSIS 是 ANSI/Unicode 无关) # 但建议 ANSI 版本优先使用此函数。 # Function PathIsDBCS_A Exch $R0 Push $R1 Push $R2 Push $R3 Push $R4 System::Call "*(&m${NSIS_MAX_STRLEN}R0)p.R1" StrCpy $R0 0 StrCpy $R2 $R1 lbl_loop: # ANSI 版取 1 个字节长度的字符,字符串遇到 0 字符表示结束了。 System::Call "*$R2(&i1.R3)" IntCmp $R3 0 lbl_done # ANSI 字符用 IsDBCSLeadByte 判断是否双字节字符的前导字节。 System::Call "kernel32::IsDBCSLeadByte(iR3)i.R4" IntCmp $R4 0 lbl_skip IntOp $R0 $R0 ! Goto lbl_done lbl_skip: # 用 CharNextA 得到下一个字符的地址 (可正确处理双字节字符)。 System::Call "user32::CharNextA(pR2)p.R2" Goto lbl_loop lbl_done: Pop $R4 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd # # 当选择的安装路径变更时,路径为空或包含双字节字符 (不限于简体中文),都不允许继续。 # 路径为空时,NSIS 会自行判断。 # # 此示例未判断是否包含空格。如有需要,请与示例一配合使用。 # Function onVerifyInstDir # 检查安装路径是否包含双字节字符 (不限于简体中文)。 Push $INSTDIR # 这里也可以换成 PathIsDBCS_A 以测试效果。 Call PathIsDBCS_A Pop $R0 Push $R0 lbl_done: FunctionEnd