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_OK
Function 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 badpath
spacecheck:
#检查磁盘空间
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 ownExit
badpath:
MessageBox MB_OK "非法路径"
ownExit:
FunctionEnd
路径选择框及逻辑
Page custom DirectorySelectPage
Var Txt_Browser
Function 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"
FunctionEnd
Function 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}
FunctionEnd
Function GetParent
#得到选中目录用于拼接安装程序名称
# Usage:
# Push "C:\Program Files\Directory\Whatever"
# Call GetParent
# Pop $R0 # $R0 equal "C:\Program Files\Directory"
Exch $R0 # input string
Push $R1
Push $R2
Push $R3
StrCpy $R1 0
StrLen $R2 $R0
loop:
IntOp $R1 $R1 + 1
IntCmp $R1 $R2 get 0 get
StrCpy $R3 $R0 1 -$R1
StrCmp $R3 "\" get
Goto loop
get:
StrCpy $R0 $R0 -$R1
Pop $R3
Pop $R2
Pop $R1
Exch $R0 # output string
FunctionEnd
Function 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 $3
FunctionEnd
页面逻辑函数(上一步、下一步、最小化、关闭)
Function RelGotoPage
#页面跳转的命令
IntCmp $R9 0 0 Move Move
StrCmp $R9 "X" 0 Move
StrCpy $R9 "120"
Move:
SendMessage $HWNDPARENT "0x408" "$R9" ""
FunctionEnd
Function onClickPre
#上一步按钮事件
StrCpy $R9 -1 #Goto the last page
Call RelGotoPage
Abort
FunctionEnd
Function onClickNext
#下一步按钮事件
StrCpy $R9 1 #Goto the next page
Call RelGotoPage
Abort
FunctionEnd
Function onMin
#最小化事件
ShowWindow $HWNDPARENT ${SW_MINIMIZE}
FunctionEnd
Function onClickCloseWithoutConfirm
#无确认关闭
System::Call 'kernel32::GetCurrentProcess()i.r0'
System::Call Kernel32::TerminateProcess(ir0,i0)
FunctionEnd
Function 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 ProgressPage
Var PB_ProgressBar
Var CurPos7Z
Var TotPos7Z
Var Progress_Current
Var Progress_Total
Function ExtractCallback
#解压回调
# MessageBox MB_OK "UpdateProgress"
#计算进度条百分比
Pop $CurPos7Z
Pop $TotPos7Z
Push $CurPos7Z
Pop $1
Push $TotPos7Z
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 0
FunctionEnd
Function 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"
!endif
FunctionEnd
Function installing
SetOutPath $INSTDIR
SetOverwrite on
#MessageBox MB_OK "installing: $INSTDIR"
#Sleep 3000
#释放压缩文件
File /r "test.7z"
GetFunctionAddress $R9 ExtractCallback
Nsis7z::ExtractWithCallback "$INSTDIR\test.7z" $R9
Delete "$INSTDIR\test.7z"
FunctionEnd
Function 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 1
FunctionEnd
文件读写
Var Select_language
Function file
#写入文件
FileOpen $0 $INSTDIR\language.txt w
IfErrors done1
FileWrite $0 "Engilsh"
FileClose $0
done1:
#读取文件
FileOpen $0 $INSTDIR\language.txt r
IfErrors done2
FileRead $0 $Select_language
FileClose $0
done2:
MessageBox MB_OK "$Select_language"
FunctionEnd
新增及删除注册表、文件夹和快捷方式
#新增注册表项
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "appName" "${APPNAME}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "number" 1
#删除注册表项
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
#新建文件夹
SetOutPath "$INSTDIR\bin"
createDirectory "$INSTDIR\newfolder"
#删除文件夹(/r为递归删除,/REBOOTOK重启后删除)
rmDir /r $INSTDIR\bin
rmDir /REBOOTOK $INSTDIR
#新建快捷方式
CreateShortcut "$Desktop\${APPNAME}.lnk" "$INSTDIR\${APPNAME}.exe"
#删除快捷方式
delete "$Desktop\${APPNAME}.lnk"
自定义check box
Page custom CheckboxPage
Var Bool_isCheck
Var check_box
Function OnClick_CheckBox
${IF} $Bool_isCheck == 1
IntOp $Bool_Run $Bool_isCheck - 1
StrCpy $1 $check_box
SkinBtn::Set /IMGID=$PLUGINSDIR\checkbox1.bmp $1
MessageBox MB_OK "$Bool_isCheck"
${ELSE}
IntOp $Bool_Run $Bool_isCheck + 1
StrCpy $1 $check_box
SkinBtn::Set /IMGID=$PLUGINSDIR\checkbox2.bmp $1
MessageBox MB_OK "$Bool_isCheck"
${EndIf}
FunctionEnd
Function CheckboxPage
#checkbox
${NSD_CreateButton} 100 100 15 15 "checkbox"
Pop $check_box
StrCpy $1 $check_box
SkinBtn::Set /IMGID=$PLUGINSDIR\checkbox2.bmp $1
GetFunctionAddress $3 OnClick_CheckBox
SkinBtn::onClick $1 $3
StrCpy $Bool_isCheck 1
FunctionEnd