Installshield进阶指南
1 说明(适用范围)
阅读对象:对IS有一定基础的使用者。
适用版本:IS10~IS12
目的 :本手册为例子工程Example Project工程的配套文档,文档中的具体代码或设置可在Example Project中看到。
本手册使用is 12中的Windows Installer-InstallscriptMSI Project作为安装讲解工程。
2 实例说明
2.1 修改环境变量
2.1.1 利用“Enviornment Variables”视图修改环境变量
可以在InstallationDesigner界面的“SystemConfiguration”-“EnviornmentVariables”节点中修改环境变量,如图:
要创建一个新的环境变量或者修改该现有的环境变量值:
1、打开Environment Variables视图
2、右键单击EnvironmentVariables并选择AddEnvironment Variable。InstallShield将添加一个默认名为 NewEnvironmentVariable x的新环境变量。输入你想创建、修改或删除的环境变量名。
3、在右边窗口的环境变量属性表中编辑属性
环境变量属性
通过配置环境变量属性,你可以指定你想在目标系统上如何编辑现有的环境变量或者创建一个新变量。每一个环境变量的描述如下:
属性 | 描述 |
Component | 选择你想把这个环境变量关联的构件。如果选择的构件安装或者卸载,根据你在环境变量的属性表中的设置,目标系统上环境变量会被创建、修改或删除。单击省略号按钮打开浏览构件对话框。 |
Value | 输入这个环境变量的路径或值。你可以使用预定义的路径,象[INSTALLDIR]Bin。要输入多个路径,使用分号分隔 |
On Install | 指明在关联的功能部件在目标系统安装时的动作。选择下列中的一个:
|
Placement | 指明相对于现有的环境变量的值如何放置Value区域内的数据。选择下列选项中的一个:
提示:如果你在On Install属性中选择了Create并且指定的环境变量在目标系统上已经存在,这个Placement属性指明这个新值如何添加到现有的环境变量中或者是否替代现有的环境变量值。尽管这样,如果指定的环境变量如果在目标系统上不存在,它将被创建并且Placement的选项会被忽略。 |
On Uninstall | 指明在关联的功能部件卸载时,环境变量是否从系统中删除。选择下面选项之一:
|
Type | 如果目标系统是Windows NT 或者Windows 2000或者更高,这个属性指明环境变量的使用方式,是整个系统环境变量还是用户环境变量。如果目标系统是Windows9x,这个属性将被忽略。选择下列选项之一: System-创建修改或删除指定系统环境变量 User-创建修改或删除用户环境变量。这个环境变量针对于那个用户运行的安装程序,即谁登录的系统。 |
2.1.2 利用脚本修改环境变量
在Behavior andLogic-Intallscript视图,可以直接在脚本中设置,修改,删除环境变量。
系统环境变量的值保存在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment中;
用户环境变量的值保存在注册表HKEY_CURRENT_USER\Environment中。
在脚本中实际上即是对此二项下的各种值进行的操作。
例子代码:(该代码修改的是系统环境变量,如要修改用户级变量,替换为szKey="Environment";
RegDBSetDefaultRoot(HKEY_CURRENT_USER);即可)
#define WM_WININICHANGE0x001A
#define HWND_BROADCAST0xffff
NUMBER nResult;
STRING szKey, szEnv;
POINTER pEnv;
begin
szKey ="SYSTEM\\CurrentControlSet\\Control\\SessionManager\\Environment";)
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
nResult=RegDBSetKeyValueEx(szKey,"Fame",REGDB_STRING,"C:\\test",-1);
if (nResult < 0)then
MessageBox("Failedto Set Environment Variable",WARNING);
else
MessageBox("SuccessfullySet Environment Variable",INFORMATION);
// Flush the NTregistry to all applications.
szEnv ="Environment";
pEnv = &szEnv;
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, pEnv );
endif;
//RebootDialog("","",SYS_BOOTMACHINE);
end;
2.2 调用外部DLL
在Behavior andLogic-Intallscript视图,通过脚本实现调用外部DLL的功能。
1、 在is脚本开头中声明需要调用的函数
如:prototypeBOOL MyDllFileName.MyFunc(STRING, STRING, STRING);
在InstallShield中如果想改变参数的值,就用传引用的方法,在STRING前加上BYREF。
2、 在需要调用函数的function中加载DLL,如:
UseDLL(SUPPORTDIR^"\\SimpleDll.dll");
nResult= ShowDlg(szDir);
UnUseDLL (SUPPORTDIR^"\\SimpleDll.dll")
以本工程中使用到的Simple.dll中三个函数为例:(具体代码参见例子工程中)
3、 有些时候有可能调试会报错:
错误号码:0x80040704
描述:DLL函数调用导致错误的堆栈
可能是原型出错:MyDllFileName.MyFunc
安装程序将立即终止。
解决方法:prototype cdecl BOOLMyDllFileName.MyFunc(STRING, STRING, STRING);
可参考网络资源:http://installshield.jaron.cn/forum/dispbbs.asp?boardID=3&ID=285266&page=1
2.3 修改XML文件
2.3.1 利用“XML File Changes”视图修改XML文件
可以在InstallationDesigner界面的“SystemConfiguration”-“XML FileChanges”节点中修改XML文件,参见“Installshield入门指南”中相关章节。
本文介绍一下在此节点中用变量给元素属性赋值的方法。
假设我们要实现用自定义变量TESTPATH的值赋给value属性,可以如下图中设置,
然后在脚本中加上MsiSetProperty(ISMSI_HANDLE,"TESTPATH",TARGETDIR);即可将安装路径赋值给TESTPATH,安装完成后,value属性的值就被替换为安装路径了。
(但目前发现通过此节点修改之后,原来的congfig文件第一行被改为:
<?xml version="1.0"encoding="UTF-16"?>,目前尚不清楚原因)。
2.3.2 利用脚本修改XML文件
在Behavior andLogic-Intallscript视图,可以直接在脚本中读取、添加、修改XML文件中的元素、属性的值。
以例子工程中的代码为例:
本段代码将用户选择的安装路径赋值给value属性,具体代码见例子工程
用户可以在脚本中创建、替换、添加、删除XML文件中的字段。
附:XML文件部分操作代码(供参考)
prototypeCreateXml(STRING);
prototypeDelteXmlNode(STRING);
prototype UpdateXmlNode(STRING);
prototypeInsertXmlNode(STRING);
//创建一个XML文档
functionCreateXml(szFile)
OBJECT objXml;
STRING strXML;
begin
//开始创建XML文档
set objXml =CreateObject("MSXML.DOMDocument");//创建一个DOM对象
if (IsObject(objXml) = FALSE ) then
MessageBox("出错,系统不支持使用DOM对象",SEVERE);
endif;
objXml.async = FALSE;
//\r\n是回车换行让内容更美观点 呵呵
strXML = "<?xmlversion=\"1.0\" encoding=\"utf-8\" ?>\r\n"
+ "<INVENTORY>\r\n"
+"<BOOK><TITLE src=\"www\">One</TITLE><PRICE>1.0</PRICE></BOOK>\r\n"
+"<BOOK><TITLE>Two</TITLE><PRICE>2.0</PRICE></BOOK>\r\n"
+"<BOOK><TITLE>Three</TITLE><PRICE>3.0</PRICE></BOOK>\r\n"
+"</INVENTORY>\r\n";
objXml.loadXML(strXML);//可以用片段很容易就弄一个XML文档出来
objXml.save(szFile); //保存
set objXml = NOTHING;
end;
//插入一个节点值
functionInsertXmlNode(szFile)
OBJECT objXml;
OBJECT objRoot,objNode;
OBJECTobjBook,objTitle,objAttributeNode;
begin
set objXml =CreateObject("MSXML.DOMDocument");//创建一个DOM对象
if (IsObject(objXml) = FALSE ) then
MessageBox("出错,系统不支持使用DOM对象",SEVERE);
endif;
objXml.async = FALSE;
objXml.load(szFile);//加载原有XML文档
set objRoot = objXml.documentElement; //取根节点
set objBook =objXml.CreateElement("BOOK");
//objBook.text = "Free";
setobjTitle = objXml.CreateElement("TITLE");
objTitle.text = "4";
set objAttributeNode =objXml.CreateNode("attribute","src","");
objAttributeNode.text = "ww";
objTitle.SetAttributeNode(objAttributeNode); //添加属性节点
objBook.appendChild(objTitle);
objRoot.appendChild(objBook); //添加节点
objXml.save(szFile); //保存
set objBook = NOTHING;
set objTitle = NOTHING;
set objXml = NOTHING;
end;
//更新某个节点值
functionUpdateXmlNode(szFile)
OBJECT objXml;
OBJECT objRoot,objNode;
begin
set objXml =CreateObject("MSXML.DOMDocument");//创建一个DOM对象
if (IsObject(objXml) = FALSE ) then
MessageBox("出错,系统不支持使用DOM对象",SEVERE);
endif;
objXml.async = FALSE;
objXml.load(szFile);//加载原有XML文档
set objRoot = objXml.documentElement; //取根节点
//MessageBox(objRoot.xml,SEVERE); //输出所有节点测试
set objNode =objRoot.selectSingleNode("BOOK/TITLE");//查找TITLE节点
//MessageBox(objNode.text,SEVERE); //输出他的值
objNode.text = "Hello";//改变值
objXml.save(szFile); //保存
set objNode = NOTHING;
set objXml = NOTHING;
end;
//删除某个节点
functionDelteXmlNode(szFile)
OBJECT objXml;
OBJECT objRoot,objNode;
begin
set objXml =CreateObject("MSXML.DOMDocument");//创建一个DOM对象
if (IsObject(objXml) = FALSE ) then
MessageBox("出错,系统不支持使用DOM对象",SEVERE);
endif;
objXml.async = FALSE;
objXml.load(szFile);//加载原有XML文档
set objRoot = objXml.documentElement; //取根节点
//MessageBox(objRoot.xml,SEVERE); //输出所有节点测试
set objNode =objRoot.selectSingleNode("BOOK/TITLE");//查找TITLE节点
//MessageBox(objNode.text,SEVERE); //输出他的值
objNode.ParentNode.removeChild(objNode);//删除该节点
objXml.save(szFile); //保存
set objNode = NOTHING;
set objXml = NOTHING;
end;
2.4 修改INI文件
2.4.1 利用“INI File Changes”视图修改ini文件
可以在InstallationDesigner界面的“ServerConfiguration”-“INI FileChanges”节点中修改ini文件,如图:
更改 .ini 文件数据
初始化(.ini)文件适合作为应用程序存储和读取的数据库。一些 .ini文件,象Boot.ini和Wininit.ini是操作系统使用的。INI文件更改视图可以让你配置在目标系统上需要修改的.ini文件。尽管你可以编辑目标系统上任意.ini文件,但是不推荐编辑系统的.ini文件。
要编辑一个 .ini文件:
1、创建一个.ini文件引用
2、添加一个段落到.ini文件中
3、添加一个关键词到.ini 文件
在你创建一个.ini的文件引用时,你必须最少建立一个构件。如果在创建.ini文件引用时没有构件,那么显示的Create a NewComponent对话框中将让你创建一个构件。
创建 .ini文件引用
要更改一个.ini文件的第一步是创建一个到你想要编辑的文件的引用。为了这个,你将需要知道你要编辑的文件的名字和位置。如果你指定的位置没有文件,那么这个文件不会发生任何改变。
要创建一个到.ini文件的引用:
1、打开INI File Changes视图
2、右键单击INI Files并从快捷菜单中选择Add INI File
3、要为你选定的条目提供一个新名称,按F2,并输入新名称即可。这个名字只是为引用使用的并不会显示给最终用户。
4、在属性表中编辑这个.ini文件的属性
在你完成创建一个到.ini文件的引用后你可以进入到下一步,向.ini文件中添加一个段落。
.ini文件属性
在安装程序中添加一个.ini文件后,设置下列属性:
属性 | 描述 |
Display Name | 输入.ini文件的名称,包括扩展名,例如,你想编辑的文件是-INIFile.ini。你输入的这个值将添加到默认语言的字符串表中。 |
Component | 选择你想与这个.ini文件关联的构件。单击浏览按钮可以显示安装程序中的所有构件列表。如果当你创建.ini文件时没有构件,将在安装程序中添加一个新构件并且这个.ini文件与之关联 |
Target | 输入你想编辑的.ini文件的文件夹路径,或者单击浏览按钮来定位这个目录。你可以从列表中选择一个Windows Installer特性文件夹。可以使用反斜杠来分隔子文件夹层次-[ProgramFilesFolder]MyCompany |
在.ini文件中添加一个段落
一旦你指定了一个想要编辑的.ini文件,你可以移动到第二步:指定文件中的那些部分需要更改。这个.ini文件被关键词分成了几个段落,每个段落都包含自己的关键词。每个关键字是用一对方括号包括起来标记的,例如[SectionName]
要配置一个.ini文件的段落:
1、打开INI File Changes视图
2、建立到一个.ini文件的引用
3、在INI Files窗口中,右键单击你想要添加内容的.ini文件,并选择AddSection
4、给这个段落设置一个显示名。你在Display Name属性中输入的名称应该与你相编辑的段落的名称匹配。为了容易定位,这个名字会存储在安装项目的字符串表里。不必要加方括号。
当你在.ini文件中添加一个段落后,你可以添加一个关键词。
向.ini文件中添加关键词
关键词是一个.ini文件中的最底层结构。这些关键词所存储的数据对于一个应用程序的使用必须是连续的。
要向一个.ini文件中添加关键词:
1、打开INI File Changes视图
2、建立一个.ini文件及要添加的段落名
3、在INI Files窗口中,右键单击一个段落并选择Add Keyword
4、为选择的关键词输入一个内部用名。这个内部名称会不显示给最终用户,只是用与你的引用。
5、在属性表中编辑关键词属性。
关键词属性
属性 | 描述 |
Display Name | 输入你想编辑的关键词的名称,它将出现在目标的.ini文件中。这个值同时存储在你的安装项目的字符串表中 |
Aciton | 选择你想要执行的动作。这些动作将定义你如果编辑这个.ini文件 Replace Old Value----选择这个选项你将用新的值来替代原有值。如果以前没有值存在,那么将添加一个新值。 Do Not Overwrite----选择这个选项是在目标文件中不存在指定的关键词是才添加新的关键词,如果.ini文件中已经有了相应的关键词那么将不会做任何改变。 Append Tag----如果你想在一个.ini值添加一个补充选择这个选项。标志是用逗号分隔的。如果你想追加一个标记的关键词不存在,那么将不会做任何改变。 Remove Whole Value----如果你想删除整个关键词和它的值那么选择这个选项。如果指定的关键词不存在,不会做任何改变。如果选择了这个选项,那么在值的部分不需要任何输入。 Remove Tag----选择这个选项可以让你从这个.ini文件中删除在value中指定的内容。 |
Data Value | 输入这个关键词的值。如果你想添加或者追加一个值,在这里输入新值。如果你想删除,输入你想删除的内容。 |
2.4.2 利用脚本修改ini文件
在Behavior andLogic-Intallscript视图,可以直接在脚本中读取、添加、修改ini文件中的字段。
以例子工程中的代码为例:
本段代码将用户选择的安装路径为值动态替换了安装目录中AdvPlant.ini文件中GroupInfo段落中的ServerInfoFilePath的原始值。这里修改的效果与在“INI File Changes”视图中修改是一样的。
用户可以使用GetProfString、ReplaceProfString、AddProfString、WriteProfString来读取、替换、添加、删除ini文件中的字段。具体例子可参见installshield帮助文档。
2.5 对IIS的Web服务扩展进行配置
对IIS基本设置已经在“Installshield入门指南”中介绍,本文主要介绍对IIS的web服务扩展进行配置。进入Installation Designer界面,选择“Server Configuration”-“Internet Information Services”节点。右键点击“Web Service Extensions”,选择“Add Web Service Extension Ins”,按下图所示对新建的web服务扩展进行相应设置。(注意:如下图中的设置可以启用ASP.NET支持,但是卸载时无法禁用ASP.NET支持,该设置将一直保持ASP.NET启用状态)。
任意的Web服务扩展和应用程序池如果与安装中的应用程序池和Web服务扩展同名,当安装程序中与之关联的功能部件卸载时,它们也会被卸载,除非相应的构件标记为永固,即勾选中“Mark Component as Permanent”。即使这些应用程序池或者Web服务扩展起初并不是由安装程序创建的,如果它们与安装程序中的同名也同样会被删除。但是有一个特例就是默认的应用程序池,叫做DefaultAppPool,永远不会被卸载程序删除。
2.6 用IS打包SQL数据库
请参见下面的网页:
2.7 各种安装类型工程简介
请参见下面的网页,对于Installscript以及Basic MSI工程介绍的比较详细:
2.8 多语言版本安装程序
一个通用的安装程序可以运行在各种不同的语言之上。根据你如何选择编译安装程序,你既可以在一个安装包内包含所有语言供用户选择,也可以为每一种语言建立一个特定的安装程序。请参见下面的网页:
2.9 平台支持能力
在ProjectAssistant页面InstallationRequirements节点,可以看到本安装程序对于安装平台的要求,在此界面可以自由选择本安装程序对于特殊操作系统的要求,默认为全选:
Installshield 12中支持Windows Vista系统。
2.10 部署一个Web程序的完整示例
下面的网页介绍了用installshield部署一个web程序的例子,请参考:
3 IS相关资料链接
遇到问题时,可以首先查找帮助,IS的帮助文档比较详细,也可以查找相关网站,下面列出几个常用的网址:
IS官方网站:http://community.installshield.com/
IS在线帮助:http://helpnet.macrovision.com/
IS中文技术论坛:http://installshield.jaron.cn/forum/index.asp
InstallShield内部库函数全集.chm:见ftp