博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NSIS脚本学习:使用 LogicLib.nsh 实现基本流程控制结构
阅读量:6239 次
发布时间:2019-06-22

本文共 7919 字,大约阅读时间需要 26 分钟。

hot3.png

LogicLib.nsh

程序的三种基本结构包括:顺序结构、分支结构、循环结构。顺序结构是最基本的结构,本文主要说明了如何在NSIS脚本中写出分支结构和循环结构。

最基本的分支结构和循环结构可以用StrCmp命令和Goto命令组成,但通过这种方式写出的代码可读性极差且难以调试。此时我们就需要用到头文件 LogicLib.nsh 中的功能了。

下面是一个示例程序,在“MyProgram”区域中输入我们要调试的代码:

!define DEBUG_PATH "E:\NSIS_Test\TmpProgram"!define OUTPUT_PATH "E:\NSIS_Test\Output"!define INSTALL_PATH "E:\NSIS_Test\Output"!include LogicLib.nshName "NSIS_VariableConstants_Test"Caption "NSIS_VariableConstants_Test"InstallDir ${INSTALL_PATH}OutFile "Galatea.exe"Section "My Program"  SetOutPath ${OUTPUT_PATH}  File /r "${DEBUG_PATH}\*.*"    ; ----------------- 在这里输入要调试的代码 -----------------  SectionEnd

我使用 HM NSIS Edit 2.0.3 工具编辑NSIS脚本,使用编译工具 makensis.exe(版本号2.46) 进行编译。

142758_RwFb_1425762.png

点击 HM NIS Edit 中“NSIS菜单”下的“编译并运行”,即编译nsi文件并运行安装包。

145428_9txS_1425762.png

LogicLib.nsh 中用于逻辑控制的语句,我都逐个写了例子,详见下文。

一、If 分支语句

例1.1:If - ElseIf - Else - EndIf

标准的 If 语句分支结构

var /GLOBAL test1StrCpy $test1 'a'${If} $test1 == 'a'  DetailPrint '$$test1 的值为 a'${ElseIf} $test1 == 'b'  DetailPrint '$$test1 的值为 b'${Else}  DetailPrint '$$test1 的值为 $test1'${EndIf}

运行结果:

$test1 的值为 a

例1.2:IfNot - Else - EndIf

IfNot 判断其后的表达式运算结果是否为假,与 If 的判断规则相反

var /GLOBAL test2StrCpy $test2 'z'${IfNot} $test2 == 'a'  DetailPrint '$$test2 的值不为 a'${Else}  DetailPrint '$$test2 的值为 $test2'${EndIf}

运行结果:

$test2 的值不为 a

例1.3:If - ElseIf - ElseIfNot - EndIf

ElseIfNot 判断其后的表达式运算结果是否为假,与 ElseIf 的判断规则相反

var /GLOBAL test3StrCpy $test3 'b'${If} $test3 == 'a'  DetailPrint '$$test3 的值为 a'${ElseIfNot} $test3 == 'b'  DetailPrint '$$test3 的值不为 b'${Else}  DetailPrint '$$test3 的值为 $test3'${EndIf}

运行结果:

$test3 的值为 b

例1.4:IfNot & Unless

Unless 与 IfNot 是等价的

var /GLOBAL test4StrCpy $test4 'z'${Unless} $test4 == 'a'  DetailPrint '$$test4 的值不为 a'${Else}  DetailPrint '$$test4 的值为 $test4'${EndUnless}

运行结果:

$test4 的值不为 a

例1.5:ElseIfNot & ElseUnless

ElseUnless 与 ElseIfNot 是等价的

var /GLOBAL test5StrCpy $test5 'b'${If} $test5 == 'a'  DetailPrint '$$test5 的值为 a'${ElseUnless} $test5 == 'b'  DetailPrint '$$test5 的值不为 b'${Else}  DetailPrint '$$test5 的值为 $test5'${EndIf}

运行结果:

$test5 的值为 b

二、If 语句与 And 和 Or 组合而成的新关键字

例2.1:AndIf & AndIfNot & AndUnless

AndIf 的逻辑,是如果前面的 If 表达式结果为真,且当前的表达式结果也为真,才继续执行它下辖代码块中的语句。

AndIfNot 的逻辑,是如果前面的 If 表达式结果为真,且当前的表达式结果为假,才继续执行它下辖代码块中的语句。

AndUnless 功能同 AndIfNot。

var /GLOBAL test6StrCpy $test6 'a'${If} $test6 == 'a'  DetailPrint '$$test6 的值为 a'${AndIf} $test6 != 'b'  DetailPrint '$$test6 的值不为 b'${AndIfNot} $test6 == 'b'  DetailPrint '$$test6 的值不为 b'${AndUnless} $test6 == 'b'  DetailPrint '$$test6 的值不为 b'${EndIf}

运行结果:

$test6 的值为 a$test6 的值不为 b$test6 的值不为 b$test6 的值不为 b

例2.2:OrIf & OrIfNot & OrUnless

AndIf 的逻辑,是如果前面的 If 表达式结果为假,且当前的表达式结果为真,才继续执行它下辖代码块中的语句。如果前面 If 表达式结果为真,也不会进入到它下辖的代码块中。

AndIfNot 的逻辑,是如果前面的 If 表达式结果为假,且当前的表达式结果也为假,才继续执行它下辖代码块中的语句。如果前面 If 表达式结果为真,也不会进入到它下辖的代码块中。

OrUnless 功能同 OrIfNot。

var /GLOBAL test7StrCpy $test7 'z'${If} $test7 == 'a'  DetailPrint '$$test7 的值为 a'${OrIf} $test7 == 'b'  DetailPrint '$$test7 的值为 b'${OrIfNot} $test7 != 'b'  DetailPrint '$$test7 的值为 b'${OrUnless} $test7 != 'b'  DetailPrint '$$test7 的值为 b'${Else}  DetailPrint '$$test7 的值为 $test7'${EndIf}

运行结果:

$test7 的值为 z

三、IfThen 与 IfNotThen

例3.1:IfThen

IfThen 语句,判断其后的表达式结果是否为真,执行第三个参数中指定的命令

var /GLOBAL test8StrCpy $test8 'a'${IfThen} $test8 == 'a' ${|} Goto x1 ${|}x1:DetailPrint 'x1'Goto endOfxy1y1:DetailPrint 'y1'Goto endOfxy1endOfxy1:DetailPrint 'endOfxy1'

运行结果:

x1endOfxy1

例3.2:IfNotThen

IfNotThen 的逻辑与 IfThen 相反,判断其后的表达式结果是否为假,执行第三个参数中指定的命令

var /GLOBAL test9StrCpy $test9 'b'${IfNotThen} $test9 == 'a' ${|} Goto y2 ${|}x2:DetailPrint 'x2'Goto endOfxy2y2:DetailPrint 'y2'Goto endOfxy2endOfxy2:DetailPrint 'endOfxy2'

运行结果:

y2endOfxy2

四、IfCmd

例4.1:IfCmd

判断其后执行命令(如MessageBox)的结果为指定结果时,执行指定的命令。

如下面这段代码中,如果在弹出的 MessageBox 中点击了“是”,则会跳转到y3

${IfCmd} MessageBox MB_YESNO "MY_YESNO" /SD IDYES IDYES ${||} Goto y3 ${|}x3:DetailPrint 'x3'Goto endOfxy3y3:DetailPrint 'y3'Goto endOfxy3endOfxy3:DetailPrint 'endOfxy3'

点击“是”时运行结果:

y3endOfxy3

五、Select 多重分支语句

例5.1:Select - Case - CaseElse - EndSelect

Select分支语句无需在每一个分支的最后添加 Break 标记,每个分支执行完毕后自动跳至 EndSelect

var /GLOBAL test10StrCpy $test10 'b'${Select} $test10  ${Case} 'a'    DetailPrint '$$test10 的值为 a'  ${Case} 'b'    DetailPrint '$$test10 的值为 b'  ${Case} 'c'    DetailPrint '$$test10 的值为 c'  ${CaseElse}    DetailPrint '$$test10 的值为 $test10'${EndSelect}

运行结果:

$test10 的值为 b

例5.2:Select - Case - Default - EndSelect

Default 的功能与 CaseElse 是一样的

var /GLOBAL test11StrCpy $test11 'd'${Select} $test11  ${Case} 'a'    DetailPrint '$$test11 的值为 a'  ${Case} 'b'    DetailPrint '$$test11 的值为 b'  ${Case} 'c'    DetailPrint '$$test11 的值为 c'  ${Default}    DetailPrint '$$test11 的值为 $test11'${EndSelect}

运行结果:

$test11 的值为 d

六、Switch 多重分支语句

例6.1:Switch - Case - CaseElse - EndSwitch

Switch 分支语句类似C语言的 switch 语句,如果不在一个 Case 的末尾添加 Break 标记,程序会一直向下执行其他 Case 中的部分。

var /GLOBAL test12StrCpy $test12 'b'${Switch} $test12  ${Case} 'a'    DetailPrint '$$test12 的值为 a'    ${Break}  ${Case} 'b'    DetailPrint '$$test12 的值为 b'    ${Break}  ${Case} 'c'    DetailPrint '$$test12 的值为 c'    ${Break}  ${CaseElse}    DetailPrint '$$test12 的值为 $test12'${EndSwitch}

运行结果:

$test12 的值为 b

例6.2:Switch - Case - Default - EndSwitch

Default 的功能与 CaseElse 是一样的

var /GLOBAL test13StrCpy $test13 'b'${Switch} $test13  ${Case} 'a'    DetailPrint '$$test13 的值为 a'    ${Break}  ${Case} 'b'    DetailPrint '$$test13 的值为 b'    ${Break}  ${Case} 'c'    DetailPrint '$$test13 的值为 c'    ${Break}  ${Default}    DetailPrint '$$test13 的值为 $test13'${EndSwitch}

运行结果:

$test13 的值为 b

例6.3:Switch - Case - CaseElse - EndSwitch WithOut Break

如果不在一个 Case 的末尾添加 Break 标记,程序会一直向下执行其他 Case 中的部分。

var /GLOBAL test14StrCpy $test14 'a'${Switch} $test14  ${Case} 'a'    DetailPrint '$$test14 的值为 a'  ${Case} 'b'    DetailPrint '$$test14 的值为 b'  ${Case} 'c'    DetailPrint '$$test14 的值为 c'  ${Default}    DetailPrint '$$test14 的值为 $test14'${EndSwitch}

运行结果:

$test14 的值为 a$test14 的值为 b$test14 的值为 c$test14 的值为 a

七、While、Do、DoWhile、DoUntil 循环

例7.1:While - EndWhile 循环

While 循环,只要后面的表达式为真,就一直循环下去

StrCpy $R1 0${While} $R1 < 5  IntOp $R1 $R1 + 1  DetailPrint $R1${EndWhile}

运行结果:

12345

例7.2:DoWhile - Loop 循环

DoWhile 循环,用法同While

StrCpy $R1 0${DoWhile} $R1 < 5  IntOp $R1 $R1 + 1  DetailPrint $R1${Loop}

运行结果:

12345

例7.3:DoUntil - Loop 循环

DoUntil 循环,只要后面的表达式值为假,就一直循环下去

StrCpy $R1 0${DoUntil} $R1 >= 5  IntOp $R1 $R1 + 1  DetailPrint $R1${Loop}

运行结果:

12345

例7.4:Do - LoopWhile 循环

Do 循环,先执行指定代码,再判断如果 LoopWhile 后面的表达式为真,就一直循环该段代码

StrCpy $R1 0${Do}   IntOp $R1 $R1 + 1  DetailPrint $R1${LoopWhile} $R1 < 5

运行结果:

12345

例7.5:Do - LoopUntil 循环

Do 循环,先执行指定代码,再判断如果 LoopUntil 后面的表达式为假,就一直循环该段代码

StrCpy $R1 0${Do}  IntOp $R1 $R1 + 1  DetailPrint $R1${LoopUntil} $R1 >= 5

运行结果:

12345

例7.6:Break & Continue

Break 和 Continue 可用于退出所有类型的循环

StrCpy $R1 0 ${While} $R1 < 5  IntOp $R1 $R1 + 1  ${If} $R1 == 2    ${Continue}  ${ElseIf} $R1 == 4    ${Break}  ${EndIf}  DetailPrint $R1${EndWhile}

运行结果:

13

例7.7:ExitDo

ExitDo 可用于退出 Do - LoopWhile、Do - LoopUntil、DoWhile、DoUntil 四类循环

StrCpy $R1 0${Do}  IntOp $R1 $R1 + 1  ${If} $R1 == 4    ${ExitDo}  ${EndIf}  DetailPrint $R1${LoopWhile} $R1 < 5

运行结果:

123

例7.8:ExitWhile

ExitWhile 只能用于退出 While 循环

StrCpy $R1 0${While} $R1 < 5  IntOp $R1 $R1 + 1  ${If} $R1 == 4    ${ExitWhile}  ${EndIf}  DetailPrint $R1${EndWhile}

运行结果:

123

八、For 与 ForEach 循环

例8.1:For - Next 循环

For 循环的第一个参数为循环变量,第二个参数为该遍历进入循环的初始值,当该变量的值在执行循环的过程中与第三个参数相等时,循环退出。

${For} $R1 1 5  DetailPrint $R1${Next}

运行结果:

12345

例8.2:ForEach 循环

ForEach 循环与 For 循环的不同之处在于,ForEach 循环还有第四、五个参数,用于指定循环的步长,第四个参数用于指定步长的正负(+、-),第五个参数用于指定步长的绝对值。

${ForEach} $R1 1 5 + 1  DetailPrint $R1${Next}${ForEach} $R1 10 2 - 2  DetailPrint $R1${Next}

运行结果:

12345108642

例8.3:Break & Continue

Break 和 Continue 可用于退出所有类型的循环

${For} $R1 1 5  ${If} $R1 == 2    ${Continue}  ${ElseIf} $R1 == 4    ${Break}  ${EndIf}  DetailPrint $R1${Next}

运行结果:

13

例8.4:ExitFor

ExitFor 可用于退出 For 循环与 ForEach 循环

${For} $R1 1 5  ${If} $R1 == 4    ${ExitFor}  ${EndIf}  DetailPrint $R1${Next}

运行结果:

1231086

END

转载于:https://my.oschina.net/Tsybius2014/blog/655817

你可能感兴趣的文章
广东工商全省工商数据中心同城数据容灾备份系统需求
查看>>
3.JSON使用
查看>>
云呼叫中心发展的市场到来了
查看>>
linux 制作大容量文档解决容量过大的问题
查看>>
Linux运维 第二阶段 (九)shell编程
查看>>
MySQL生成随机数
查看>>
无需软件合并多个TS流文件
查看>>
HDU——2119 Matrix
查看>>
我的友情链接
查看>>
SCCM 2012 sp1无法连接远程数据库命名实例
查看>>
Linux学习之查看文件和文件夹大小
查看>>
明明白白你的Linux服务器——硬件篇(1)
查看>>
osgi启动级别
查看>>
php防止快速刷屏留言
查看>>
python 登录验证程序
查看>>
Linux
查看>>
限制linux 用户使用su命令转化root权限
查看>>
headfirst PMP-忽视项目职责范围会带来哪些问题?
查看>>
PHP缓存学习之redis
查看>>
以lnmp为基础搭建discuz论坛
查看>>