NSIS打包脚本

NSIS打包脚本的编写

变量分为局部变量和全局变量( 变量的声明使用var 全局变量再加上/GLOBAL)

Var example

Function testVar
  # 函数内部定义变量必须是全局变量。不能定义局部变量
  Var /GLOBAL example2

  # 变量的使用:$+变量名
  # 变量的赋值:使用StrCpy函数
  StrCpy $example "example value"
  StrCpy $example2 "another example value"
FunctionEnd
# 函数的调用: Call FuncName
# 使用在卸载函数中的自定义函数,函数名称必须以un.开头,包括嵌套的函数,也是这个规则
Call testVar

在这里插入图片描述

内置的变量,可直接使用,主要目的是跨函数调用。

NSIS还内置了一系列变量,如$0~$9,$R0 ~ $R9,这些变量无需声明即可直接使用。其中,$0常用于临时存储地址或回调函数的参数。这些变量在脚本执行过程中可以存储和传递数据,方便实现各种复杂的安装逻辑。$R0 一般是栈内存首个寄存器。

	#获取安装默认语言
	System::Call 'kernel32::GetUserDefaultUILanguage() i .r0' 
	System::Call 'kernel32::GetLocaleInfoA(i 1024, i ${LOCALE_SNATIVELANGNAME}, t .r1, i ${NSIS_MAX_STRLEN}) i r0' 
	System::Call 'kernel32::GetLocaleInfoA(i 1024, i ${LOCALE_SNATIVECTRYNAME}, t .r2, i ${NSIS_MAX_STRLEN}) i r0' 
	System::Call 'kernel32::GetLocaleInfoA(i 1024, i ${LOCALE_SLANGUAGE}, t .r3, i ${NSIS_MAX_STRLEN}) i r0'  
	;MessageBox MB_OK|MB_ICONINFORMATION "Your System LANG Code is: $0. $\r$\nYour system language is: $1. $\r$\nYour system language is: $2. $\r$\nSystem Locale INFO: $3." 
	Pop $0 
	IntOp $0 $0 & 0xFFFF
	;MessageBox MB_OK|MB_ICONINFORMATION "Your System LANG Code is: $0. " 
	${if} $0 == 2052
		StrCpy $R4 "0"	#0:汉语 1:英语 2:繁体中文
	${elseif} $0 == 1028
		StrCpy $R4 "2"	#0:汉语 1:英语 2:繁体中文
	${elseif} $0 == 3076
		StrCpy $R4 "2"	#0:汉语 1:英语 2:繁体中文
	${elseif} $0 == 5124
		StrCpy $R4 "2"	#0:汉语 1:英语 2:繁体中文
	${else}
		StrCpy $R4 "1"	#0:汉语 1:英语 2:繁体中文
	${endif}

$R4存储的是多语言的标志。
在这里插入图片描述

静态变量,函数编译期已经确定了,运行期不会被改变的变量。

使用的时候除了固定前缀$符号,要再配合花括号{}使用。比如:${EXE_NAME}

内置语法命令,也是使用${}包裹指定的命令,并且命令是首字母大写。如:

${If}
${Endif}

当然,不推荐手写,使用vscode工具,安装NSIS语言识别插件,我们输入If,首字母大写,就会有语法提示,选到符合的语言上面,自动就出来了。其他语法类似。
语法缩进要严格执行,否则会出错。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

常用功能

# 文件删除,文件夹级联删除
Delete "文件名称"
RMDir "文件夹"	
# 跳转语句 Goto
# label_to_jump_to | +offset| -offset| user_var(target)
Goto label  # 跳转到指定的标签label对应的代码段,最常用
Goto +2		# 相对偏移量,跳转到后2条指令处
Goto -2		# 相对偏移量,跳转到前2条指令处
Goto $0		# $0如果有值,跳转到指定的地址(如果指定了用户变量,则跳转到绝对地址(通常您希望从GetLabelAddress之类的函数获取此值))

# 使用nsProcess插件查杀程序
Function un.KillExe
	Var /GLOBAL myexe
	Exch $R0
	StrCpy $myexe $R0
	# 查进程
	nsProcess::_FindProcess $myexe
	Pop $R0
	${If} $R0 == 0
		# 杀进程
		nsProcess::_KillProcess $myexe
		pop $R0
		# 失败
		${If} $R0 != 0
			${If} $R4 == "0"
				StrCpy $R8 "请手动关闭$myexe"
				StrCpy $R9 "确定"
			${ElseIf} $R4 == "2"
				StrCpy $R8 "請手動關閉$myexe"
				StrCpy $R9 "確定"
			${Else}
				StrCpy $R8 "Please Close $myexe manually."
				StrCpy $R9 "yes"
			${EndIf}
			StrCpy $R7 "0"
			Call un.ShowMsgBox
		${EndIf}
	${EndIf}
FunctionEnd


## 模拟在卸载程序中执行删除文件操作,区分处理删除成功和失败的逻辑
Function un.ErrorHandler
	MessageBox MB_OKCANCEL "ErrorHandler!"
FunctionEnd

Function un.myFunc
	Exch $R0
	Var /GLOBAL myExe
	StrCpy $myExe $R0
	MessageBox MB_OK "$myExe"
	# IfErrors jump_to_if_error [jump_to_if_no_error]
	ClearErrors # 清楚错误,否则后面判断会不准确
	Delete "d:\\cccc.txt"
	IfErrors 0 +3
		Call un.ErrorHandler 		# 0, +1
		Goto +2						# +2
		MessageBox MB_OK "没有错误"  # +3
	MessageBox MB_OK "主流程结束了"
FunctionEnd

# 执行具体的卸载 
Function un.onUninstall
	push 88
	Call un.myFunc
	Goto InstallAbort
	# do stuff
InstallAbort:
FunctionEnd

# Return语句,退出函数或段
Function func
  StrCmp $0 "return now" 0 +2
    Return
  # do stuff
FunctionEnd

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用 Prism 框架进行 WPF 开发时,可以使用 `ErrorsContainer` 类来进行数据验证。`ErrorsContainer` 类是一个 Prism 框架提供的数据验证类,可以将数据验证错误信息保存在 `Errors` 字典中,并且可以绑定到 UI 上进行显示。 以下是将 `ErrorsContainer` 封装到 View Model 基类里的代码示例: ```csharp using Prism.Mvvm; using Prism.Commands; using Prism.Validation; public abstract class BaseViewModel : BindableBase, IValidatableBindableBase { protected ErrorsContainer<string> errorsContainer; public BaseViewModel() { errorsContainer = new ErrorsContainer<string>(OnErrorsChanged); } public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public System.Collections.IEnumerable GetErrors(string propertyName) { return errorsContainer.GetErrors(propertyName); } public bool HasErrors { get { return errorsContainer.HasErrors; } } protected virtual void OnErrorsChanged([CallerMemberName] string propertyName = null) { ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); } protected void ValidateProperty<T>(Expression<Func<T>> propertyExpression, T value) { var propertyName = ((MemberExpression)propertyExpression.Body).Member.Name; errorsContainer.ClearErrors(propertyName); Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = propertyName }); } protected void ValidateObject() { errorsContainer.ClearErrors(); Validator.ValidateObject(this, new ValidationContext(this, null, null)); } protected bool SetPropertyAndValidate<T>(ref T field, T value, Expression<Func<T>> propertyExpression) { if (EqualityComparer<T>.Default.Equals(field, value)) { return false; } field = value; RaisePropertyChanged(propertyExpression); ValidateProperty(propertyExpression, value); return !HasErrors; } } ``` 在这个基类中,我们继承了 Prism.Mvvm 中的 `BindableBase` 类,并实现了 `IValidatableBindableBase` 接口。在构造函数中,我们初始化了 `ErrorsContainer` 对象,并将 `OnErrorsChanged` 方法作为参数传入。`OnErrorsChanged` 方法会在数据验证错误信息发生变化时被调用,我们可以在这个方法中更新 UI。 在 `GetErrors` 方法中,我们通过传入的属性名来获取对应的验证错误信息。在 `HasErrors` 属性中,我们判断当前是否存在验证错误信息。 在 `ValidateProperty` 方法中,我们通过传入的属性表达式和属性值来进行属性验证,并将验证结果保存到 `ErrorsContainer` 中。在 `ValidateObject` 方法中,我们通过对整个对象进行验证,并将验证结果保存到 `ErrorsContainer` 中。 最后,在 `SetPropertyAndValidate` 方法中,我们通过传入的字段引用、属性表达式和属性值来进行属性赋值并进行验证。 使用这个基类的子类在进行数据验证时,只需要在属性的 set 方法中调用 `SetPropertyAndValidate` 方法,并传入对应的字段引用、属性表达式和属性值即可。同时,在 UI 中绑定数据时,需要使用 `ErrorsContainer` 中的 `GetErrors` 方法来获取对应的错误信息,并将结果绑定到 UI 上进行显示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值