2023年12月3日发(作者:)
NSIS常用函数#NSIS常用函数##多语言设置#定义多语言!insertmacro MUI_LANGUAGE "English"!insertmacro MUI_LANGUAGE "SimpChinese"Caption "$(LNG_NAME)"Name "$(LNG_NAME)"!define APPNAME "shenjianji"LangString LNG_NAME ${LANG_ENGLISH} "appname"LangString LNG_TITLE ${LANG_ENGLISH} "app installer"LangString LNG_NAME ${LANG_SIMPCHINESE} "软件名称"LangString LNG_TITLE ${LANG_SIMPCHINESE} "软件安装器"LangString LNG_NAME ${LANG_JAPANESE} "応用"LangString LNG_TITLE ${LANG_JAPANESE} "アプリケーションインストーラ"Function .onInit #选择语言(加入到combobox) Push "" Push ${LANG_SIMPCHINESE} Push "Simplified Chinese" Push ${LANG_JAPANESE} Push "Japanese" Push ${LANG_ENGLISH} Push "English" Push A #显示语言选择框 LangDLL::LangDialog "Installer Language" "Please select the language of the installer" Pop $LANGUAGE StrCmp $LANGUAGE "cancel" 0 +2 Abort ${If} ${LANG_SIMPCHINESE} = $Language MessageBox MB_OK "简体中文:$(LNG_TITLE)" ${ElseIf} ${LANG_ENGLISH} = $Language MessageBox MB_OK "English: $(LNG_TITLE)" ${ElseIf} ${LANG_JAPANESE} = $Language MessageBox MB_OK "日本語: $(LNG_TITLE)" ${EndIf}FunctionEnd##判断系统位数${If} ${RunningX64} MessageBox MB_OK "x64"${Else} MessageBox MB_OK "x86"${EndIf}##安装路径合法性及磁盘剩余空间判断Var Path_OKFunction pathcheck #MessageBox MB_OK "onWelcomepageNext:$INSTDIR" Push 0 Pop $Path_OK #检查安装路径 #INSTDIR不能为空路径 StrCmp $INSTDIR "" badpath #INSTDIR不能为磁盘根目录 StrCpy $R0 $INSTDIR "" -2 StrCmp $R0 ":" badpath StrCpy $R0 $INSTDIR "" -1 StrCmp $R0 ":" badpath # SetOutPath "$INSTDIR" IfFileExists "$INSTDIR*.*" 0 +2 Goto spacecheck Goto badpathspacecheck: #检查磁盘空间 StrCpy $R3 "$INSTDIR" 3 ${DriveSpace} $R3 "/D=F /S=G" $R2 Push $R2 Pop $Disk_Space ${If} $Disk_Space == 0 MessageBox MB_OK "磁盘空间不足" Goto ownExit ${EndIf} #检查通过 Push 1 Pop $Path_OK Goto ownExitbadpath: MessageBox MB_OK "非法路径"ownExit:FunctionEnd##路径选择框及逻辑Page custom DirectorySelectPageVar Txt_BrowserFunction OnChange_DirRequest #textarea编辑事件 Pop $0 System::Call "user32::GetWindowText(i $Txt_Browser,t .r0,i ${NSIS_MAX_STRLEN}) i .n" StrCpy $INSTDIR $0 MessageBox MB_OK "OnChange_DirRequest $INSTDIR"FunctionEndFunction OnClick_DirectorySelect #点击浏览按钮事件 Pop $0 Push $INSTDIR
Call GetParent Pop $R0
Push $INSTDIR Push "" Push "${APPNAME}" Pop $R1 nsDialogs::SelectFolderDialog "$(LNG_SELECTFOLDER)" "" Pop $0 ${If} $0 == "error" Return ${EndIf} ${If} $0 != "" StrCpy $INSTDIR "$0$R1" system::Call `user32::SetWindowText(i $Txt_Browser, t "$INSTDIR")` ${EndIf}FunctionEndFunction GetParent #得到选中目录用于拼接安装程序名称 # Usage: # Push "C:Program FilesDirectoryWhatever" # Call GetParent # Pop $R0 # $R0 equal "C:Program FilesDirectory" Exch $R0 # input string Push $R1 Push $R2 Push $R3 StrCpy $R1 0 StrLen $R2 $R0loop: IntOp $R1 $R1 + 1 IntCmp $R1 $R2 get 0 get StrCpy $R3 $R0 1 -$R1 StrCmp $R3 "" get Goto loopget: StrCpy $R0 $R0 -$R1 Pop $R3 Pop $R2 Pop $R1 Exch $R0 # output stringFunctionEndFunction DirectorySelectPage #更改目录控件创建 ${NSD_CreateDirRequest} 50 100 300 26 "$INSTDIR" Pop $Txt_Browser ${NSD_OnChange} $Txt_Browser OnChange_DirRequest #浏览按钮 ${NSD_CreateBrowseButton} 350 100 80 26 "浏览" Pop $2 StrCpy $1 $2 GetFunctionAddress $3 OnClick_DirectorySelect SkinBtn::onClick $1 $3FunctionEnd##页面逻辑函数(上一步、下一步、最小化、关闭)Function RelGotoPage #页面跳转的命令 IntCmp $R9 0 0 Move Move StrCmp $R9 "X" 0 Move StrCpy $R9 "120"Move: SendMessage $HWNDPARENT "0x408" "$R9" ""FunctionEndFunction onClickPre #上一步按钮事件 StrCpy $R9 -1 #Goto the last page Call RelGotoPage AbortFunctionEndFunction onClickNext #下一步按钮事件 StrCpy $R9 1 #Goto the next page Call RelGotoPage AbortFunctionEndFunction onMin #最小化事件 ShowWindow $HWNDPARENT ${SW_MINIMIZE}FunctionEndFunction onClickCloseWithoutConfirm #无确认关闭 System::Call 'kernel32::GetCurrentProcess()i.r0' System::Call Kernel32::TerminateProcess(ir0,i0)FunctionEndFunction onClickClose #确认关闭 MessageBox MB_YESNO "$(LNG_WARNNING_CONFIRMEXIT)" /SD IDYES IDNO noexit System::Call 'kernel32::GetCurrentProcess()i.r0' System::Call Kernel32::TerminateProcess(ir0,i0)noexit:FunctionEnd##解压文件并更新进度条直接使用File释放文件因为没有回调所以没有实时进度,只能做假进度。而使用Nsis7z::ExtractWithCallback时,每释放一个文件都能触发一次回调,从而实现进度条更新Page custom ProgressPageVar PB_ProgressBarVar CurPos7ZVar TotPos7ZVar Progress_CurrentVar Progress_TotalFunction ExtractCallback #解压回调 # MessageBox MB_OK "UpdateProgress" #计算进度条百分比 Pop $CurPos7Z Pop $TotPos7Z Push $CurPos7Z Pop $1 Push $TotPos7Z Pop $2 Pop $2 Push $1 Pop $Progress_Current Push $2 Pop $Progress_Total System::Int64Op $1 * 100 Pop $3 System::Int64Op $3 / $2 Pop $0 #MessageBox MB_OK "$1 $2 $0" #更新进度条 SendMessage $PB_ProgressBar ${PBM_SETPOS} $0 0FunctionEndFunction NSD_TimerFun GetFunctionAddress $0 NSD_TimerFun nsDialogs::KillTimer $0 !if 1 #是否在后台运行,1有效 GetFunctionAddress $0 installing BgWorker::CallAndWait MessageBox MB_OK "finish" !else Call installing MessageBox MB_OK "finish" !endifFunctionEndFunction installing SetOutPath $INSTDIR SetOverwrite on #MessageBox MB_OK "installing: $INSTDIR" #Sleep 3000 #释放压缩文件 File /r "test.7z" GetFunctionAddress $R9 ExtractCallback Nsis7z::ExtractWithCallback "$INSTDIRtest.7z" $R9 Delete "$INSTDIRtest.7z"FunctionEndFunction ProgressPage #安装进度条 ${NSD_CreateProgressBar} 10 200 300 10 "" Pop $PB_ProgressBar #进度条初始化 Push 0 Pop $Progress_Current Push 100 Pop $Progress_Total Push 0 Pop $CurPos7Z Push 100 Pop $TotPos7Z #开启定时器,更新进度条 GetFunctionAddress $0 NSD_TimerFun nsDialogs::CreateTimer $0 1FunctionEnd##文件读写Var Select_languageFunction file #写入文件 FileOpen $0 $ w IfErrors done1 FileWrite $0 "Engilsh" FileClose $0done1: #读取文件 FileOpen $0 $ r IfErrors done2 FileRead $0 $Select_language FileClose $0done2: MessageBox MB_OK "$Select_language"FunctionEnd##新增及删除注册表、文件夹和快捷方式 #新增注册表项 WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${APPNAME}" "appName" "${APPNAME}" WriteRegDWORD HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${APPNAME}" "number" 1 #删除注册表项 DeleteRegKey HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${APPNAME}" #新建文件夹 SetOutPath "$INSTDIRbin" createDirectory "$INSTDIRnewfolder" #删除文件夹(/r为递归删除,/REBOOTOK重启后删除) rmDir /r $INSTDIRbin rmDir /REBOOTOK $INSTDIR #新建快捷方式 CreateShortcut "$Desktop${APPNAME}.lnk" "$INSTDIR${APPNAME}.exe" #删除快捷方式 delete "$Desktop${APPNAME}.lnk"##自定义check boxPage custom CheckboxPageVar Bool_isCheckVar check_boxFunction OnClick_CheckBox ${IF} $Bool_isCheck == 1 IntOp $Bool_Run $Bool_isCheck - 1 StrCpy $1 $check_box SkinBtn::Set /IMGID=$ $1 MessageBox MB_OK "$Bool_isCheck" ${ELSE} IntOp $Bool_Run $Bool_isCheck + 1 StrCpy $1 $check_box SkinBtn::Set /IMGID=$ $1 MessageBox MB_OK "$Bool_isCheck" ${EndIf}FunctionEndFunction CheckboxPage #checkbox ${NSD_CreateButton} 100 100 15 15 "checkbox" Pop $check_box StrCpy $1 $check_box SkinBtn::Set /IMGID=$ $1 GetFunctionAddress $3 OnClick_CheckBox SkinBtn::onClick $1 $3 StrCpy $Bool_isCheck 1FunctionEnd


发布评论