1、InstallShield学习笔记 开发语言InstallShield学习笔记Script Language Revision HistoryDATEREVISIONAUTHORDESCRIPTIONTable of Contents1 前言 32 数据类型和结构体 32.1 基本数据类型 32.2 多元素数据类型 32.2.1 数组(Array) 32.2.2 列表(List) 42.3 数据结构 42.3.1 声明数据结构 42.3.2 存取数据结构 43 变量与常量 53.1 变量的定义及赋值 53.2 常量的定义及赋值 53.3 匈牙利命名法 54 操作符与表达式 64.1 逻辑操作符
2、 64.2 逻辑操作符 64.3 关系操作符 74.4 字符串操作符 74.5 地址相关操作符 85 代码块 85.1 条件语句 85.1.1 if-then-endif结构 85.1.2 if-then-else-endif结构 85.1.3 if-elseif-endif结构 85.1.4 if-goto结构 95.1.5 嵌套if-else-endif结构 95.1.6 switchendswitch结构 95.2 循环语句 105.2.1 forendfor结构 105.2.2 whileendwhile结构 105.2.3 repeatuntil结构 105.3 跳转语句 115.4
3、 中止及退出语句 116 函数 116.1 函数声明定义 116.2 函数参数传递 126.3 函数调用 126.4 函数返回 127 错误处理 137.1 捕获错误 137.2 函数错误 138 预处理语句 149 代码注释 149.1 单行注释 149.2 多行注释 1510 使用内置变量及函数 1510.1 预定义常量 1510.2 预定义脚本变量 1510.3 系统变量 1510.4 内置函数 151 前言InstallScript是专门用来编写InstallShield安装程序的脚本语言。它语法类似C语言,是一种过程化的语言。除了内置的几百个常用函数(Function)之外,用户可以
4、通过这种script自己编写脚本,实现各种复杂需求,从而设计出灵活且强大的安装程序。本文档是笔者在学习InstallShield脚本的过程中,查阅InstallShield 2009 IDE的联机帮助,结合个人学习心得体会,写出的学习笔记。鉴于篇幅有限,本文仅就InstallShield Script各方面的基本用法做了一些总结,仅供新手入门作参考之用。若读者有意深入研究高级进阶内容,请参考InstallScript IDE(集成开发环境)自带的联机帮助,或者在网上搜寻参考资料 ( 附:InstallShield社区论坛:, 2 数据类型和结构体2.1 基本数据类型 跟其它的高级语言一样,In
5、stallShield Script也支持常见的基本数据类型,列举如下:类型数值注释BOOL布尔型其值可以是TRUE 或 FALSE,或者1或0char 或CHAR字符型其值可以是一个单字节的符号(比如“a”, “A”),或一个代表符号的ASCII 数字值(比如127)string或STRING字符串型,比如”string text”字符串是一个包含若干字符(双字节)的数组Int或INT双字节整数型一般使用上,等同于NUMBER类型short或SHORT短整数型一般使用上,等同于NUMBER类型Long或LONG长整数型一般使用上,等同于NUMBER类型number或NUMBER数值型带正负符
6、号的四字节整数,其值范围在-2,147,483,648 和+2,147,483,647之间pointer或POINTER指针型跟C语言中的指针类似,也是一种对变量的内存地址的引用,通常在变量名前使用取址符号&获得对其地址的引用VARIANT变量类型可用于数组HWND窗口句柄型对窗口对象的引用,通常用CmdGetHwndDlg or GetWindowHandle 函数来初始化注:上表中没有列出一些极少使用的类型(比如LPSTR,VARIANT,VOID,WSTRING等)。 若要获得相关信息,请参考InstallShield IDE的联机帮助。2.2 多元素数据类型 数组(Array)和列表(
7、List)是包含多元素的复杂数据类型,在此节单独介绍。2.2.1 数组(Array)InstallShield Script中的数组如同其它高级语言里面的数组一样,也是一个无序的同类型的元素集合,用户通过数组名加上方括号和下标数字进行存取元素的值,如下例子所示:2.2.2 列表(List)InstallShield Script中的列表是一种有序元素的集合体,比数组复杂得多。列表中的元素除了可以象数组那样使用元素下标获取之外,也可以通过其它元素的位置向前或者向后追溯而得到。InstallShield Script提供了很多对列表进行操作的方法,详见InstallShield IDE的联机帮助,
8、这里仅介绍几种常用的方法:2.3 数据结构 在某些特殊场合,需要将一些基本数据类型的变量组合成一个复合的数据结构。2.3.1 声明数据结构/ 以下片断声明一个名为STAFF的数据结构类型,/ 它由两个STRING元素和一个NUMBER元素组成typedef STAFF begin STRING szName(20); STRING szTitle(10; NUMBER nAge; end;声明数据结构时的注意事项:1. 数据结构不能在函数体(function body)内部声明。2. 数据结构中的某元素如果是STRING类型,必须加上数组长度,比如此例子中的STRING szName(20)
9、。3. 数据结构体中不能使用BYREF关键字,也不要使用POINTER类型元素。2.3.2 存取数据结构数据结构中的元素,通过点号进行引用,如下所示:/ 以下片断创建一个STAFF的数据结构,并给其元素赋值STAFF structSTAFF;structSTAFF.szName = “Tom Xu”;structSTAFF.szTitle = “Engineer”;structSTAFF.nAge = 30;/ 以下片断读取此数据结构中的元素值到三个STRING类型的变量中STRING szData1, szData2, szData3;szData1 = structSTAFF.szName
10、;szData2 = structSTAFF.szTitle;szData2 = structSTAFF.nAge;存取数据结构时的注意事项:1. 两个数据结构类型的变量之间不能直接互相赋值(用=操作符赋值)。3 变量与常量3.1 d变量的定义及赋值在InstallShield Script中,根据作用范围,变量分为两种类型: 局部变量 - 定义在函数变量区的变量(位置在function关键字和begin关键字之间),它们只能在该函数体内部被赋值或读取。 全局变量 - 定义主程序块(main program block)之外且不在函数内部的变量(位置一般在script文件的头部分), 它们在该
11、setup script文件的全局范围内(该变量定义之后的任何地方)都可以被赋值或读取。/ 以下片断示范了全局变量和局部变量的定义,以及它们的可见范围STRING szGlobal; / 声明一个全局变量prototype DisplayMsg (STRING); / 声明函数原型 function DisplayMsg (szMsg) / 为前面的方法原型定义函数体 begin STRING szLocal; / 声明一个局部变量,注意它是定义在函数体内部 szLocal = “I am a Local variable”; / 给前面这个局部变量赋值 szGlobal = “I am a
12、Global variable”; / 给函数体外部定义的那个全局变量赋值 end;3.2 常量的定义及赋值在InstallShield Script中,常量的使用跟其它高级语言中的常量相同,常量名为大写字母.且其值在定义时被初始化后,不能被再次赋值。注意:常量的定义必须在前面使用#define关键字,紧跟常量名和常量值,用空格隔开,切记不可用等于号赋值,并且句尾不可带分号,如下面的例子所示/ 以下片断示范了常量的定义以及使用#define TITLE Welcome / 定义并初始化了一个名为TITLE的字符串型常量#define VERSION 670 / 定义并初始化了一个名为VERSI
13、ON的数值型常量STRING szResult;szResult = TITLE; / 正确用法:引用TITLE常量的值TITLE = “Updated Welcome”; / 错误用法:给TITLE常量再次赋值,编译时会报错3.3 匈牙利命名法在InstallShield Script中,对变量(和函数参数),常量的命名一般使用”匈牙利命名法”,即在名字前面加上两位小写字母的前缀(prefix),用来表明该变量的数据类型,比如名为nResult的变量表示其值是NUMBER型,名为szName的变量表示其值是STRING型。另外,在函数体(function body)定义中,对函数参数名也应用
14、这种命名法,可以让函数调用者明白该传入什么类型的参数值。比如,我们定义了一个函数 function MyFunction(szName,nOption),那么其它人马上明白:调用该函数时应该传入两个参数值,第一个为STRING型,第二个为NUMBER型。下表中列出了“匈牙利命名法“中常用的前缀,我们在实际使用中应该尽量遵循这些规则:前缀表示数据类型变量命名例子使用范围b布尔型 (BOOL)bResult用于布尔型的变量(variable)或常量(constant)bv布尔型 (BOOL)bvOK只用于布尔型的函数参数, 该参数在函数内部会被赋值c字符型(CHAR)cInput用于字符型的变量(
15、variable)或常量(constant)const常量constPrefix只用于常量(constant)h窗口句柄型(HWND)hWindow只用于窗口句柄型的变量(variable)i整数型(INT)iLevel用于整数型的变量(variable)或常量(constant)l长整数型(LONG)lAmount用于长整数型的变量(variable)或常量(constant)lv长整数型(LONG)lvCount只用于长整数型的函数参数, 该参数在函数内部会被赋值list列表类型(LIST)listIChoices只用于列表类型的变量(variable)n数值型(NUMBER)nValue
16、用于数值型的变量(variable)或常量(constant)nv数值型(NUMBER)nTmpValue只用于数值型的函数参数, 该参数在函数内部会被赋值p指针型(POINTER)pVarAddress只用于指针型的变量(variable)pstruct指针型(POINTER)pstructDataStruct只用于指向数据结构(data structure)的指针型的变量(variable)s短整数型(SHORT)sOption用于短整数型的变量(variable)或常量(constant)sz字符串型(STRING)szName用于字符串型的变量(variable)或常量(constan
17、t)sv字符串型(STRING)svTmpName只用于字符串型的函数参数, 该参数在函数内部会被赋值struct数据结构型(自定义)structMyStruct只用自定义的数据结构型(data structure)的变量(variable)注:1. 在InstallShield Script中,请注意标志符号(包含变量名等)是大小写敏感的(e.g. szName != szNAME).2. 在上表中提到的bv,lv,nv,sv等前缀都是代表对应数据型的一种可变变量,一般由调用主程序传递给函数,在函数体内被赋值。比如常见的读取注册表z键值的函数,后面三个参数都会在函数体内被赋值,如下:RegD
18、BGetKeyValueEx ( szKey, szName, nvType, svValue, nvSize );4 操作符与表达式以下板块列出了InstallShield Script中常用的各种类型的操作符号及相关表达式。对某些甚少使用的操作符若有未尽之处,请查阅InstallShield IDE的联机帮助4.1 逻辑操作符符号含义表达式例子表达式解释加法32 (=5)两个数字值相加减法32 (=1)两个数字值相减*乘法3 * 2 (=6)两个数字值相乘/除法3 / 2 (=1.5)两个数字值相除取模5 % 2 (=1)两个数字值取模4.2 逻辑操作符符号含义表达式例子表达式解释&AND
19、expression1 & expression2两逻辑值执行与操作。只有当表达式expression1和expression2都为TRUE时,返回TRUE;否则返回FALSE.|ORexpression1 | expression两逻辑值执行或操作。当表达式expression1或者expression2任一为真时,返回TRUE;只有当两者都为FALSE时才返回FALSE!NOT!expression1逻辑值取反。当表达式expression1为FALSE时返回TRUE;反之则返回FALSE。4.3 关系操作符符号含义表达式例子表达式解释等于nValue1 = nValue2当nValue1
20、与nValue2相等时,返回TURE;否则返回FALSE。大于nValue1 nValue2当nValue1大于nValue2时,返回TURE;否则返回FALSE。小于nValue1 =大于或等于nValue1 = nValue2当nValue1大于或者等于nValue2时,返回TURE;否则返回FALSE。=小于或等于nValue1 General Information -String Table)。例如: 如果String Table中有定义一个名为IDS_PROT, 值为”Accela”的条目。那么在script中使用IDS_PROT表达式: 得到的值将会是”Accela”这个字符串。
21、4.5 地址相关操作符符号含义表达式例子表达式解释&由变量取地址pPointer = &szValue&和*是一对互逆的操作符。&用来取一个变量的地址值,返回指针(pointer)类型值;而*用来取一个指针指向的变量值,返回该变量的类型。例如:POINTER pPointer;STRING szValue, szResult;szValue = “Gordon Chen”;pPointer = &szValue; / 取变量szValue的地址szResult = *pPointer; /取指针pPointer指向的变量*由地址取变量SzValue = *pPointer;5 代码块5.1 条
22、件语句5.1.1 if-then-endif结构这种结构只包含一个if分支。首先判断if中表达式的返回值,如果为TRUE则执行then关键字后面的代码块,否则直接跳过该代码块。/ 以下片断示范了标准的if-then-endif代码块结构NUMBER nAnswer;nAnswer = AskYesNo ( Are you sure you want to exit?, NO );if (nAnswer = YES) then MessageBox (You choose to exit !, WARNING); endif;5.1.2 if-then-else-endif结构这种结构包含一个i
23、f和一个else分支。首先判断if中表达式的返回值,如果为TRUE则执行then关键字后面的代码块,否则就执行else关键字后面的代码块。/ 以下片断示范了标准的if-then-else-endif代码块结构NUMBER nAnswer;nAnswer = AskYesNo ( Are you sure you want to exit?, NO );if (nAnswer = YES) then MessageBox (You chose to exit !, WARNING); elseMessageBox (You gave up to exit !, WARNING); endif;5
24、.1.3 if-elseif-endif结构这种结构包含一个if和若干个elseif分支,注意没有else分支。首先判断if中表达式的返回值,如果为TRUE则接着执行其后then关键字后面的代码块。否则就依次逐一匹配后面的每个elseif关键字后面的表达式,如果发现其值为TRUE就会执行它对应的then关键字后面的代码块。/ 以下片断示范了标准的if-elseif-endif代码块结构NUMBER nAnswer;nAnswer = AskYesNo ( Are you sure you want to exit?, NO );if (nAnswer = YES) then MessageBo
25、x (You chose to exit !, WARNING); elseif (nAnswer = YES) then MessageBox (You gave up to exit !, WARNING);elseif (nAnswer = 9999) then MessageBox (Are you joking? It is impossible!, WARNING); endif;5.1.4 if-goto结构这种结构包含一个if分支,它在逻辑执行上类似于前面介绍的if-then-endif结构,所不同的是此处使用goto关键字跳转到一个标号(label)的定义处去执行代码。另外,
26、这种用法必须要求条件表达式后面紧跟goto声明(if和goto写在一行),另外它也不能使用else和endif关键字。/ 以下片断示范了标准的if-goto代码块结构NUMBER nAnswer;nAnswer = AskYesNo ( Are you sure you want to exit?, NO );if (nAnswer = YES) goto Action_YES; / 如果条件为TRUE,则跳转到标号处开始执行/* 这里有一些其它代码,但是它们将会被直接跳过 */ Action_YES:MessageBox (You chose to exit !, WARNING); 5.1.5 嵌套if-else-endif结构这种嵌套结构基于普通的的if-then-endif结构而来,在if代码块或者else代码块中都可以分别嵌入另外的if-then-endif代码结构。可以在if和else两者中同时加入嵌套,也可以只在两者之一中加入嵌套,如下例:NUMBER nAnswer;if (szType = “Staff”) then if (szTitle = “Manager”) then / 此处为第一级if里面嵌套的if-else-endif结构 MessageBox (Welcome,You have full access!
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1