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) 进行编译。

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

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

一、If 分支语句

例1.1:If - ElseIf - Else - EndIf

标准的 If 语句分支结构

var /GLOBAL test1
StrCpy $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 test2
StrCpy $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 test3
StrCpy $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 test4
StrCpy $test4 'z'
${Unless} $test4 == 'a'DetailPrint '$$test4 的值不为 a'
${Else}DetailPrint '$$test4 的值为 $test4'
${EndUnless}

运行结果:

$test4 的值不为 a

例1.5:ElseIfNot & ElseUnless

ElseUnless 与 ElseIfNot 是等价的

var /GLOBAL test5
StrCpy $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 test6
StrCpy $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 test7
StrCpy $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 test8
StrCpy $test8 'a'
${IfThen} $test8 == 'a' ${|} Goto x1 ${|}
x1:
DetailPrint 'x1'
Goto endOfxy1
y1:
DetailPrint 'y1'
Goto endOfxy1
endOfxy1:
DetailPrint 'endOfxy1'

运行结果:

x1
endOfxy1

例3.2:IfNotThen

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

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

运行结果:

y2
endOfxy2

四、IfCmd

例4.1:IfCmd

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

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

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

点击“是”时运行结果:

y3
endOfxy3

五、Select 多重分支语句

例5.1:Select - Case - CaseElse - EndSelect

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

var /GLOBAL test10
StrCpy $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 test11
StrCpy $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 test12
StrCpy $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 test13
StrCpy $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 test14
StrCpy $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 < 5IntOp $R1 $R1 + 1DetailPrint $R1
${EndWhile}

运行结果:

1
2
3
4
5

例7.2:DoWhile - Loop 循环

DoWhile 循环,用法同While

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

运行结果:

1
2
3
4
5

例7.3:DoUntil - Loop 循环

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

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

运行结果:

1
2
3
4
5

例7.4:Do - LoopWhile 循环

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

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

运行结果:

1
2
3
4
5

例7.5:Do - LoopUntil 循环

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

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

运行结果:

1
2
3
4
5

例7.6:Break & Continue

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

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

运行结果:

1
3

例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

运行结果:

1
2
3

例7.8:ExitWhile

ExitWhile 只能用于退出 While 循环

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

运行结果:

1
2
3

八、For 与 ForEach 循环

例8.1:For - Next 循环

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

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

运行结果:

1
2
3
4
5

例8.2:ForEach 循环

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

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

运行结果:

1
2
3
4
5
10
8
6
4
2

例8.3:Break & Continue

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

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

运行结果:

1
3

例8.4:ExitFor

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

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

运行结果:

1
2
3
10
8
6

END

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

NSIS脚本学习:使用 LogicLib.nsh 实现基本流程控制结构相关推荐

  1. NSIS脚本学习:创建 MUI 界面使用的自定义语言包文件(nlf nsh)

    NSIS脚本的语言包文件,存放在以下目录: NSIS安装目录\Contrib\Language files 在这个目录下有很多语言包,一般简体中文使用的语言包是 SimpChinese.nlf 和 S ...

  2. NSIS脚本学习:判断版本并安装.NET Framework运行环境

    前言 目前开发的程序以基于.net的应用程序为主,程序开发好后,需要进行安装包的生成,及setup文件的生成. 常见的是NSIS工具,之前一直用的单文件打包工具,不适合将运行环境加进去,因此开始使用更 ...

  3. NSIS学习记录(三)————NSIS脚本简介

    文章目录 一.介绍 二.脚本结构 Installer Attributes Page Sections Functions 一.介绍 标题NSIS脚本是有特定语法规则的规范语言. 可以用任何文本编辑器 ...

  4. 关于NSIS脚本的Demo

    这个NSIS脚本是打包公司的整个Release项目工程. 用NSIS编译器编译下就可以了. ; Script generated by the HM NIS Edit Script Wizard.!i ...

  5. 使用NSIS脚本制作一个安装包

    大部分人第一次看到NSIS脚本都是一脸懵逼的.因为它这个脚本的结构乍一看上去就非常奇怪,不作说明的话是看不懂的. 编写脚本命令的时候要非常注意,命令要按照规定写在脚本中不同的段落里,也就是说,命令的先 ...

  6. 全方位掌握nsis脚本

    全方位掌握nsis脚本 NSIS 确实是一个不错的安装程序制作软件.新版本 2.0a7 真正实现了中文支持和支持 WinXP 的安装对话框. 不过要用它实现漂亮的安装界面和完美的安装功能就必须好好的写 ...

  7. NSIS脚本文件格式

    4.1 脚本文件格式 一个 NSIS 脚本文件 (.nsi) 就是一个包含了脚本代码的文本文件. 命令 命令行的格式为: '命令 [参数]' File "myfile" 注释 以 ...

  8. NSIS 脚本知识汇总

    转载来源:NSIS 打包脚本基础 - 走看看 简介 NSIS(Nullsoft Scriptable Install System)是一个开源的 Windows 系统下安装程序制作程序.它提供了安装. ...

  9. 《更胜黎明前的琉璃色》简体中文汉化版安装包1.1 NSIS脚本

    这次这补丁的安装包是赶出来的,真糟糕.不过至少能拿BMW3补丁的NSIS脚本作为基础来改,倒也没多麻烦. 这次有几个需求: 1.需要做splash 2.需要添加左侧的图片 3.需要播放背景音乐 4.需 ...

最新文章

  1. JDK1.8快速入门
  2. ZooKeeper Java Example(官方例子)
  3. golang管道channel与协程goroutine配合使用示例
  4. Visual stuidio 快捷键的修改、查询
  5. python新手入门项目推荐_推荐:一个适合于Python新手的入门练手项目
  6. 学习Spring-Cloud –编写微服务
  7. css绘画三角形,实现一些图形
  8. teamviewer 可用设备上限_河北环保碎石机价格-设备_久诺机械设备
  9. 28. Location replace() 方法
  10. Tomcat6 无法登陆Tomcat Manager
  11. RT-Thread 应用笔记 - libmodbus RTU 编译问题的解决
  12. BGA集成电路脚位识别
  13. Confession:关于本博客以及实习
  14. 为什么要有uboot?
  15. 【历史上的今天】8 月 25 日:Linux 诞生;我国第一个计算机科学技术研究所成立
  16. jvm-sandbox实战之编写简单案例
  17. svn操作之合并分支
  18. android 防火墙,安卓防火墙-安卓防火墙(Android Firewall) 安卓版v2.2.2-PC6安卓网
  19. python编程else是什么意思_python条件判断if/else - python基础入门(8)
  20. IEEE期刊/会议模板

热门文章

  1. Miles per gallon to kilometers per liter
  2. Python:nii格式的核磁共振图像(MRI)的读取、处理、显示操作(以缩放操作举例)
  3. Android studio 导出安卓APP软件方法
  4. 如何使用JMeter自身代理录制测试脚本
  5. 使用paypal-php-sdk开发php国际支付
  6. 十大javascript难点
  7. 蚂蚁金服推出 BaaS 平台:巨头角逐之下,商业机会正快速来临
  8. 配置表单和报表以使用HTTP Server(OHS)
  9. 捡到的苹果手机怎么解id锁_苹果手机换id通讯录没了怎么恢复?超全教程,建议收藏!...
  10. iOS-内购注意 沙盒二次验证