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_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

猜你喜欢

转载自blog.csdn.net/aa13058219642/article/details/81811290