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
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值