[转]一个完整的Installshield安装程序实例
Posted 绣春刀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[转]一个完整的Installshield安装程序实例相关的知识,希望对你有一定的参考价值。
Installshield安装程序实例—基本设置一
前言
Installshield可以说是最好的做安装程序的商业软件之一,不过因为功能的太过于强大,以至于上手和精通都不是容易的事情,之前都是用Installshield的Project Assistant对付过去的,这次做这个安装程序,为了实现一些功能,必须写代码,国内外现成的资料很少,而且很多都语焉不详,自己反复啃了多次,对比Installshiel自带的help,才明白资料所表达的意思。这个安装程序虽然比较简陋,在行家眼里可能是小菜一碟,但是也花了笔者一个星期的时间,阅读了很多资料,啃了好几天英文help,集成了很多先驱者的经验,也费了自己不少心血做成的,对每一段代码的用处、每一个用到的函数都进行了详细的说明,因此转载时请务必保留转载出处和由艾泽拉斯之海洋女神出品的字样;如需刊登,请与作者联系。
在此要感谢吞硬币的小猪,天下晓明,余满青,海洋C++乐园(此海洋不是彼海洋)等大虾在互联网上的无私奉献,他们的贴子和博客给了我很大启示。
因为本人是做java出身的,因此对这种类C++语言还是第一次接触,有理解不当之处,请朋友们指正。欢迎Email至little_fairycat@126.com
正文
需求:公司做了一个软件产品,
1. 该软件运行需要JDK环境(不是JRE,因为该软件要向windows注册一个服务,用到了JavaService,JDK才支持这个功能;不过这里侧重于判断是否安装了某软件是否安装,而不是纠缠于该装JDK还是该装JRE);
2. 由于是Server-Client形式的,需要允许用户选择安装组件,比如A机只装Server端,B机只装Client端;
3. 文档不打包在安装程序里,直接存放在光盘文件夹下方便用户查看,同时允许用户指定是否安装文档到计算机上(为什么这样做,后面说明详细原因);
4. 该软件会以授权形式发放给用户,不同的用户,软件本身可能相同,而不同的只是授权文件和一些配置,因此希望授权文件和配置文件不打包在安装程序里,而直接存放在光盘里,以减少可能的重复打包安装程序的劳动;
5. 在安装完毕后,希望能自启动程序(因为该软件需要在安装完毕后启动一个程序,该程序实现向Windows注册服务的功能,该程序最好由安装程序启动,而不是由客户手动启动)。
6. 希望有反安装程序
本文提到的“外部”指不打包在安装程序里的,与安装程序一起存放在光盘里的一些文件夹,这些文件夹包含了安装中所需要的文件,同时也可能有其他用途,因此不适合直接压缩打包在安装程序里。
该实例实现了如下功能:
1. 显示软件许可协议
2. 判断是否安装了本软件所需要的先决软件JKD1.6.0_04,如无,则启动外部安装程序进行安装(同样原理可以用来判断是否安装了其他软件,只要该软件在注册表中有键值)
3. 安装允许用户选择需要安装的组件
4. 用户的输入信息、所选安装路径、所选安装组件将显示在安装界面上(Installshield虽然自带了此界面,但是默认是显示为空的,需要写脚本来显示信息)
5. 根据用户选择的组件,在开始菜单显示程序的快捷方式(同样适用于桌面快捷方式,后面做详细说明)
6. 根据用户选择的组件,从外部文件夹拷贝相应的文件到安装目标路径的文件夹中
7. 根据从外部拷贝进来的文件,创建快捷方式(这里主要是拷贝文档,并在开始菜单中创建快捷方式)
8. 在安装结束时,显示readme.txt文件
9. 在安装结束后,启动指定的程序
10. 完美卸载
笔者所用的环境为Installshield 12 Premier Edition,Windows XP with SP2, 该环境下建立的工程可以直接使用在Installshield 2008 Premier Edition下,Installshield 2008在打开Installshield 12所建的工程时会提示你是否需要进行Upgrade,确认即可,软件会自动为你进行升级,很方便。
下面我们一步一步来建立一个基本的工程,并且使用脚本来完善和丰富所需功能
第一部分:基本设置
1. 打开Installshield 12 Premier Edition,新建一个Installscript MSI Project,这种被称之为半脚本程序,因为兼具Basic Project基本类型和Installscript Project全脚本类型两者的优点,我比较喜欢用。像我这样需求的,既要用到Wizard的便利,又想写一点脚本来实现一点自定义操作的,就比较适合用这种类型啦。
选择类型为Windows Installer | InstallScript MSI Projcet,输入工程名,指定工程所在的文件夹。
2. 界面会切换到Project Assistant,我们先从这里开始把工程的基本组件和基本文件建立好。
3. 在Project Assistant界面的底部,会有一个引导动作条,在建立该工程的基本结构和文件时,我们都将在此界面进行操作,下文都将以“引导条”来指代这个引导动作条。
4. 点击引导条上的Application Information
这里输入:
公司名,公司名将会出现在Setup.exe的注解中
软件名,将会出现在安装过程的左上角标题栏上
版本号,没看到在哪,不过自己比较方便地知道自己在编译哪个版本的软件
公司网址,没看到在哪,而且如果该公司没有网址呢?而且这里有点bug,好像默认的值总是会报一个String_ID1为空的错误,自己输入一个网址就不会报错。
是否在你创建了更新时自动通知最终用户,没用过,我都选了No。
选择一个图标,这个图标会出现在“添加或删除程序”里,我一般用默认的,当然你可以替换成自己想要的图标。
5. 点击引导条上的Installation Requirement
这里选择对操作系统和一些软件的需求。根据自己需要来选择是否要求操作系统的版本,已经是否要求安装了某些软件。
6. 点击引导条上的Installation Architecture
这是个十分有用的设置,对于本文所用的分布式软件来说非常合适,分布式软件的每个组件可以设置为一个Feature,用户可以自由选择安装某些功能。
将选项Do you want to customize your Installation选择为Yes。
点击选中根节点Installation Architecture,点击New创建新的Feature,可以为每个Feature指定新名称。
还可以在Feature下创建子Feature,比如如果文档Feature下包括软件本身文档,和软件所需的运行环境的文档,那么可以创建两个子Feature,分别包含两种文档,用户在安装时就可以选择安装部分或者全部文档了。这里我们没有用到子Feature,用途和普通Feature一样。
这里,建立好所有Feature后,我们将切换到Installation Designer做一个设置
找到Installation Designer页面上左边导航树Organization | Features分支,你会看到这里Features都显示为原始的名称,而非我们改过的名字,因为Feature有Name和Display Name两种名称,我们刚才改的不过是Display Name,为了便于查看和使用,我们在这里把Name也改一下
注意Name不可以有空格,可以使用下划线
继续切换回Project Assistant
Installshield安装程序实例—基本设置二
7. 点击引导条上的Application Files
我们将在这里对安装路径进行微调,并且为每个Feature指定需要安装的文件
这里我不想使用Program Files | Company Name | Product Name这个路径,我想使用Program Files | Product Name,我直接点击选中My Product Name[INSTALLDIR]拖动到ProgramFileFolder下,还可以直接将My Product Name 改成自己想要的文件夹名字
接下来,为每个Feature指定要安装的文件。
打开这个下拉列表,所有的Feature都在这里,按顺序来给每一个Feature建立文件夹,并且导入所需的文件。
选择第一个Feature, 即Server,点击My Product Name[INSTALLDIR]节点,右键点击,在菜单上选择New Folder来创建一个文件夹。
创建一个Server文件夹,这个文件夹将用来存放该组件需要的一些文件。
再在Server文件夹下创建一个icon文件夹,存放该组件所用的图标。
然后为该Feature添加安装时该Feature要安装的文件。
这里我们建立的icon文件夹是用来存放这个feature在后面要建立快捷方式时使用的图标的。为这个icon文件夹添加相应的图标文件,并且记住图标文件的来源文件夹,后面设置快捷方式的时候要用。
点击选中要添加文件的文件夹,然后点击右下角的Add Files,然后添加文件
接下来我们为Feature添加文件夹,如果这个文件夹中的全部文件都为这个Feature所需。添加文件夹的好处在于只要文件夹位置和名称不变,那么文件夹里面的文件都是动态加载的,有多少加载多少,不用考虑文件名的改动带来的影响。
点击选中要添加文件夹的文件夹,然后点击右下角的Add Folders,然后添加文件夹。
选中文件夹,点击确定。
会询问你是否要使用动态文件链接,我都选择确定,好处就在于我刚才上面所述。
显示了源文件夹,如果这个文件夹下有子文件夹,并且也需要一并添加进来的话,务必钩选Include subfolders选项。
这里还允许做一些简单设置来包含或者排除一些特定文件,支持通配符。
点击OK确定加入文件夹。
如法炮制为每个Feature建立文件夹,并且添加文件,最后效果如图所示
Document这个Feature,除了文件所用的图标外,什么都不要添加,后面我们将用安装时实时拷贝的方式来拷贝文档进来。
8. 接下来我们为可执行文件创建快捷方式。
点击引导条上的Application Shortcuts
点击New新建一个快捷方式
选择一个要建立快捷方式的Feature。
如果要建立快捷方式的程序为非.exe形式,请把Files Of选择选为All Files(*.*)格式。
我们的程序安装目标路径设置在Program Files下,因此双击[ProgramFilesFolder]打开,层层点击进入。
我们这里要为client.bat建立一个快捷方式,因为这个是启动用的批处理文件。
Installshield可以自动监测到.exe文件的存在,自动生成快捷方式,用户只需要做一些适当修改即可。
新建的快捷方式将出现在这里,名字不好听,样子也不好看,我们将为它改一个名字,并且换一个图标。
选中快捷方式,点击Rename,并且为这个快捷方式改一个适当的名字。
注意右边的几个选项。
Create shortcut in Start Menu,将在开始菜单里创建一个快捷方式。
Create shortcut on Desktop,将在桌面上创建一个快捷方式。
Use alternate shortcut Icon,替换快捷方式的图标
Associate a file extension with the shortcut’s target,没用过,不知道什么意思。
我们在这里将只创建开始菜单的快捷方式,因此钩选第一项。
钩选第三项,并且点击Browse来浏览图标。
请回想刚才在为Feature添加文件的时候,每个feature都添加了对应的icon。这里,请把浏览的文件夹设定为刚才添加icons所用的文件夹,通俗的说,就是你刚才从哪儿添加一个图标进feature的,现在还是从哪儿添加的这个图标。
其实这一点我是一直很费解的,当初不知道要这么选择图标,随便从外面一个任意文件夹里添加了一个图标,以至于打包后死活找不到图标,后来经过试验才知道这个被选中的图标文件要拷贝进来,打包进安装文件才可以。这一点上不能不提一下visual studio,这个工具做安装程序虽然功能一般,但是思想还是不错的,当它的组件指定拷贝了图标文件后,在建立快捷方式时,快捷方式使用的图标是指向虚拟的安装目标路径下的图标文件的,而不是指定到这个实实在在的源文件夹。这一点差别就体现出了思想上的差异。
如法炮制为每个Feature指定快捷方式,Document除外,因为我们在这个feature里除了图标文件外什么都没有添加。
至此我们为每个可执行程序添加了开始菜单下的快捷方式。
我们再切换去Installation Designer,找到System Configuration | Shortcuts。
看到快捷方式在开始菜单中是以 公司名 | 软件名 | 快捷方式 这种形式存在的。事实上我是不喜欢这种形式了,想想点开一层还有一层,不如直接了当来得干脆,因此做一些修改。
这里我改成了如下设置
不要告诉我你不会改,直接拖动Test文件夹往Program Menu(即开始菜单下的那个“所有程序”)下一塞即可,然后删除掉多余的Company Name文件夹。
9. 可能刚才在Project Assistant界面有人已经注意到了左边栏上More Options下Create an uninstallation shortcut这个诱人的字样了。
可是我要告诉你,如果你选择了这种方式建立卸载快捷方式的话,你会很沮丧地发现:
a) 似乎只有在安装某个feature的时候这个卸载快捷方式才会出现(当然,就是那个default feature,这种要命的feature形式决定了每个文件或者快捷方式都必须明确地归属到某个feature下),因此,当你的客户只选择了其他feature安装时,这个卸载方式不会出现,而他必须去“添加或卸载程序”里面去卸载
b) 如果你写脚本使得安装时会拷贝一些外部文件进来,那么这些文件在这种卸载方式下是删除不掉的。(如果你确实想保存这些文件,你可以在脚本里设置它们属性为permanent,这个属性可以保证什么卸载方式都不能删除你的这些文件)。
所以这里我们忽视这个卸载快捷方式的存在,而将在后面采用脚本形式实现完美卸载。
10. 点击引导条上的Application Registry
向注册表写键和键值,由于本工程不需要,忽略之。有需要的朋友可以查阅相关资料,不难。
11. 点击引导条上的Installation Location
这个是用来设置安装包的语言的,选择了多个语言后,用户可以在安装界面开始的时候选择安装时所用的语言;不过作为一个公司产品来说,这么偷懒,客户的印象是要打折扣的,所以还是选个单语言吧,该什么语言的安装包就什么语言的安装包,各归各。
不过你又会沮丧地发现,如果要选择一种其他语言作为Default Language,好像又报错了。
这个问题当时折腾了我一个星期(当然那时候才接触Installshield,还一窍不通),最后问了技术支持才得以解决。
切换去Installation Designer,找到Installation Information | General Information,看到String Tables下面是什么?对,所有你选的语言都列出来了,选中你要的语言,右键,选择Make Default,OK,再切换回Project Assistant去把所有不要的语言统统去掉钩选即可。
看到此处,已经变成了English为默认语言了。
12. 点击引导条上的Build Installation。
打包安装盘的设置,本人从来不用这个选项,都用工具条上的Release Wizard。
至此,第一部分基本完成。如果是一些没有特别要求的安装包,这部分讲解的内容足够可以做一个基本的安装包了
Installshield安装程序实例—高级设置一
第二部分:脚本编程
在开始进行编程前,我们先明确一下我们要用编程来弥补前面设置的哪些功能的不足
1. 显示软件许可协议
2. 判断是否安装了本软件所需要的先决软件JKD1.6.0_04,如无,则启动外部安装程序进行安装(同样原理可以用来判断是否安装了其他软件,只要该软件在注册表中有键值)
3. 用户的输入信息、所选安装路径、所选安装组件将显示在安装界面上(Installshield虽然自带了此界面,但是默认是显示为空的,需要写脚本来显示信息)
4. 根据用户选择的组件,从外部文件夹拷贝相应的文件到安装目标路径的文件夹中
5. 根据从外部拷贝进来的文件,创建快捷方式(这里主要是拷贝文档,并在开始菜单中创建快捷方式)
6. 在安装结束时,显示readme.txt文件
7. 在安装结束后,启动指定的程序
8. 完美卸载
脚本编程这部分都将在Installer Designer这个界面进行。后面不再赘述。
Installshield大小写敏感,因此请严格按照示例上所写的大小写规则来书写。例:字符串变量STRING和string都支持,但是String不支持。
1. 显示软件许可协议
1. 添加许可协议文本
在左边导航树上找到Behavior and Logic | Support Files/Billboards选项。这个选项允许用户添加一些在安装过程中需要用到的文件。
中间的导航栏会显示对应的选项
在Support Files分支下,会显示一个Language Independent和所有你所选择的语言类型。 Language Independent意为,如果你在这里分支下做了设置,那么无论选择用何种语言安装,这个设置都会生效;而各个语言类型意为,如果你在某语言下做了设置,那么这个设置只有在选择了用这种语言安装的时候才会生效。
点击Language Independent,这次我们将在这个分支下进行试验。
在右边的Files栏中右键点击,在弹出菜单上选择Insert Files选项。
选择事先撰写好的许可协议的文本文件,插入到Files栏中。
许可协议允许两种文本格式:txt和rtf格式,此处我们采用 txt格式。
2. 然后切换到Behavior and Logic | InstallScript选项,
3. 中间的导航栏Files下有一个默认的Rul文件Setup.Rul,我们这个工程的全部installscript代码都将写在这个默认文件里
4. 点击选中Setup.Rul节点,右边会显示该文件的可编程面板。
5. 许可协议应该在一开始运行安装程序的时候就显示,也就是在拷贝数据前。请在第一个下拉框中选择Before Move Data选项,然后在第二个下拉框中选择OnBegin选项(不要因为默认显示的是这两个选项,而不做这个打开下拉列表进行选择的动作,否则软件检测不到你选择了选项,无法自动添加代码),则编程界面上会自动添加一些代码如下图所示。当然,如果你手动敲代码上去也是可以的。
6. 我们将在function OnBegin()的函数体里面写代码来显示刚才添加的许可协议文本的内容,直接把下面的代码拷贝到OnBegin()函数的begin和end;之间就可以了
Disable (BACKBUTTON);
if(!MAINTENANCE)then
SdLicense2 ("License ", "", "", SUPPORTDIR ^ "2.txt", FALSE);
endif;
7. 代码解释
************************************************************************
Disable (BACKBUTTON);
将“上一步”按键设置为不可用。安装程序在一开始的时候会有一个默认的开始界面,第二步才显示许可协议,一般来说没必要回退回去看这个什么都没有的开始界面,因此将回退按键设置为不可用
************************************************************************
if(!MAINTENANCE)then
endif;
这一个条件用来判断安装程序处于何种状态,安装、修复、重新安装或卸载状态,后三者都属于MAINTENANCE状态,因此判断只有在正常安装的状态才显示许可协议
************************************************************************
SdLicense2 ("License ", "", "", SUPPORTDIR ^ "2.txt", FALSE);
这个函数用于在界面上显示所用的许可协议。Help里对该函数的构造函数如下
SdLicense2 ( szTitle, szOpt1, szOpt2, szLicenseFile, bLicenseAccepted );
参数一:szTitle,显示在界面左上角的标题,如果填写空字符串””,则显示为默认值”License Agreement”。
参数二:szOpt1,我们常见许可协议界面上会有两个选项,一个是“同意”,一个是“不同意”,szOpt1和szOpt2就是这两个选项,如果填写空字符串,则会显示为默认值"I accept the terms of the license agreement"和"I do not accept the terms of the license agreement"。
参数三:szOpt2,见参数二的说明
参数四:szLicenseFile,指定需要显示的文档,包含路径和带扩展名的文档名。我们刚才把许可协议文本放在supportfile选项下了,这个路径在Installshield里有专门的静态变量来指明,即SUPPORTDIR,然后再添加上带扩展名的文档名,这里是2.txt。静态变量路径和引号引起来的路径之间用^符号来连接。
参数四:bLicenseAccepted,布尔型变量,TRUE状态,则在许可协议界面上默认选中的是那个“同意”的选项;不过好像一般更常见的是默认选中为“不同意”的选项,因此这里可以填入FALSE。
这是许可协议的界面。当用户选择了I accept the terms of the license agreement这个选项后,Next按键可用,安装程序可以继续。(请忽略这里显示的许可协议内容…网上有很多软件许可协议的范本供下载...)
小结:至此,许可协议就添加完毕,在安装执行的时候,用户就可以看到许可协议显示在界面上,并且只有选择了“同意”选项后,安装程序才会往下执行。
显示许可协议的函数一共有三个SdLicense,SdLicenseRtf和SdLicense2,参数略有不同,显示的界面也略有不同,用户可以根据喜好来选择。目前我常用的就是SdLicense2这个函数,显示的界面符合大多数目前流行的安装界面的习惯。
2. 判断是否安装了本软件所需要的先决软件或运行环境
1. 代码还是在OnBegin()函数体内实现,直接把下面的代码拷贝到OnBegin()函数的begin和end;之间就可以了
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
if (RegDBKeyExist ("SOFTWARE\\\\JavaSoft\\\\Java Development Kit\\\\1.6.0_04") < 0) then
LaunchAppAndWait (SRCDISK^"jdk\\\\jdk-6u4-windows-i586-p.exe","", LAAW_OPTION_WAIT);
endif;
2. 代码解释
************************************************************************
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
设置一下默认的注册表键值根节点为HKEY_LOCAL_MACHINE。
打开注册表可以看到“我的电脑”下的根节点有HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE等。我们这次要寻找的JDK软件的注册表键值在HKEY_LOCAL_MACHINE下,因此要把根键设置为HKEY_LOCAL_MACHINE。
表告诉我你不知道怎么看注册表,开始-〉运行-〉输入命令regedit
***********************************************************************
RegDBKeyExist ("SOFTWARE\\\\JavaSoft\\\\Java Development Kit\\\\1.6.0_04") < 0)
判断是否存在键值SOFTWARE\\\\JavaSoft\\\\Java Development Kit\\\\1.6.0_04,这个是JDK1.6.0_04安装时向注册表写入的值;
RegDBKeyExist( szSubKey );如果存在键值则返回1,否则返回小于0的随机数字。
***********************************************************************
LaunchAppAndWait (SRCDISK^"jdk\\\\jdk-6u4-windows-i586-p.exe","", LAAW_OPTION_WAIT);
当上面判断了没有安装JDK1.6.0_04这个软件时,则启动光盘里jdk文件夹下的jdk-6u4-windows-i586-p.exe安装程序来安装。
这个函数在help里是这样叙述的:
LaunchAppAndWait ( szProgram, szCmdLine, nOptions );
参数一:szProgram,即要启动的程序。这里我们写入的参数是SRCDISK^"jdk\\\\jdk-6u4-windows-i586-p.exe", SRCDISK指源盘,安装程序所在的盘,光盘和硬盘都可以。"jdk\\\\jdk-6u4-windows-i586-p.exe"源盘下jdk文件夹下的jdk-6u4-windows-i586-p.exe安装程序。
参数二:szCmdLine,如果要启动的程序需要从命令行读入参数来启动,那么在这里写入对应的参数值;我们这里不需要,因此输入空字符串””。
参数三:nOptions,静态变量,不同的静态变量会得到不同的执行结果,比如无等待安装,静默安装,鼠标外形改变等等。详情请参阅Installshield自带的Help。这里我们用LAAW_OPTION_WAIT,即当JDK安装结束后(无论是正常安装了,还是用户点击取消了安装),安装程序才往下继续。
这里可以看到,当点击了同意许可协议的时候,安装程序会自动检测是否安装了JDK,如果没有安装,则弹出安装界面。
这里在函数体里面,没有对找不到JDK安装程序,以及安装出错等情况做判断。如果用户有需要,可以添加一个消息框,提示在找不到安装程序或者安装出错的情况下,用户可以手动地安装需要的软件。代码可以改写为
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
if (RegDBKeyExist ("SOFTWARE\\\\JavaSoft\\\\Java Development Kit\\\\1.6.0_04") < 0) then
if(LaunchAppAndWait (SRCDISK^"jdk\\\\jdk-6u4-windows-i586-p.exe","", LAAW_OPTION_WAIT)<0)then
MessageBox ("You haven\'t installed JDK 1.6.0_04 yet! ", INFORMATION);
endif;
endif;
小结:至此,判断运行所需软件的功能结束,用户可以自己试验一下判断多个软件。用法就是重复上述代码功能,仍在OnBegin()函数体内执行。
3. 用户的输入信息、所选安装路径、所选安装组件显示在安装界面上
Installshield是自带这个界面的,在安装过程中用户可以看到这个界面,但是这个界面上的信息是空的,这一点让人很是疑惑,怀疑是Installshield的bug。因此我们不得不手动地实现这个功能。
1. 这个功能需要在OnFirstUIBefore()函数体中实现,选择Before Move Data | OnFirstUIBefore选项
2. 选择了这个选项后,软件会自动在编程界面生成大量代码,如图所示,这里的每一个Dlg_SdXXXX都对应着一个界面,例如Dlg_SdWelcome就是对应着最初开始的欢迎界面。如果开发人员对这些很熟悉,可以在这里对每一个界面编程设置。
3. 找到Dlg_SdStartCopy这个界面选项,我们将在这里对已有的代码进行改动,使之显示用户输入的用户信息、所选安装路径和组件等信息
4. 首先定义所需变量。
在begin前定义6个feature的名字和两个NUMBER类型的变量,即蓝色字串。之前在第一部分我们定义了6个可用的feature,这里就要对这6个feature进行一些判断。
在begin字样后对这6个feature赋值,所赋的值就是我们在第一部分定义的feature的名字(Name, not Display Name)。
//---------------------------------------------------------------------------
function OnFirstUIBefore()
NUMBER nResult, nSetupType, nvSize, nUser;
STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile;
STRING szLicenseFile;
LIST list, listStartCopy;
BOOL bCustom;
STRING szFeatureName1;
STRING szFeatureName2;
STRING szFeatureName3;
STRING szFeatureName4;
STRING szFeatureName5;
STRING szFeatureName6;
NUMBER bvOpt1,bvOpt2;
begin
// TO DO: if you want to enable background, window title, and caption bar title
// SetTitle( @PRODUCT_NAME, 24, WHITE );
// SetTitle( @PRODUCT_NAME, 0, BACKGROUNDCAPTION );
// Enable( FULLWINDOWMODE );
// Enable( BACKGROUND );
// SetColor(BACKGROUND,RGB (0, 128, 128));
szFeatureName1 ="Server";
szFeatureName2 ="Client";
szFeatureName3 ="Watch_Portion";
szFeatureName4 ="Log_Portion";
szFeatureName5 ="Report_Portion";
szFeatureName6 ="Document";
5. 在Dlg_SdStartCopy的listStartCopy = ListCreate( STRINGLIST ); 和ListDestroy(listStartCopy);之间的nResult = SdStartCopy( szTitle, szMsg, listStartCopy );之前加入如下代码。
ListAddString(listStartCopy,"Customer Information:",AFTER);
ListAddString(listStartCopy,"User Name: " + svName,AFTER);
ListAddString(listStartCopy,"Company Name: " + svCompany,AFTER);
ListAddString(listStartCopy,"Destination Location: " + INSTALLDIR,AFTER);
switch (nSetupType)
case TYPICAL : ListAddString(listStartCopy,"Setup Type: Typical",AFTER);
case COMPACT: ListAddString(listStartCopy,"Setup Type: Compact",AFTER);
case CUSTOM: ListAddString(listStartCopy,"Setup Type: Custom",AFTER);
endswitch;
ListAddString(listStartCopy," ",AFTER);
ListAddString(listStartCopy,"The Selected Feature:",AFTER);
if (FeatureIsItemSelected(MEDIA, szFeatureName1)=1) then
ListAddString(listStartCopy," "+szFeatureName1,AFTER);
endif;
if (FeatureIsItemSelected(MEDIA, szFeatureName2)=1) then
ListAddString(listStartCopy," "+szFeatureName2,AFTER);
endif;
if (FeatureIsItemSelected(MEDIA, szFeatureName3)=1) then
ListAddString(listStartCopy," "+szFeatureName3,AFTER);
endif;
if (FeatureIsItemSelected(MEDIA, szFeatureName4)=1) then
ListAddString(listStartCopy," "+szFeatureName4,AFTER);
endif;
if (FeatureIsItemSelected(MEDIA, szFeatureName5)=1) then
ListAddString(listStartCopy," "+szFeatureName5,AFTER);
endif;
if (FeatureIsItemSelected(MEDIA, szFeatureName6)=1) then
ListAddString(listStartCopy," "+szFeatureName6,AFTER);
endif;
6. 代码解释
*************************************************************
ListAddString(listStartCopy,"XXXXXX",AFTER);
把要显示的信息添加到list里去,这个list的内容稍后会添加到界面上进行显示。
Help里对这个函数是这样描述的:ListAddString ( listID, szString,以上是关于[转]一个完整的Installshield安装程序实例的主要内容,如果未能解决你的问题,请参考以下文章
使用InstallShield打包windriver驱动-转
安装 Installshield 2010 前需要卸载无关的应用程序
InstallShield6.0 如何卸载已经制作完成的安装程序?