第一部分:基本设置 ............................................................................................................... 1
新建Installscript MSI Project .......................................................................................... 1 引导动作条 ....................................................................................................................... 2
1. Application Information ........................................................................................ 2 2. Installation Requirement ....................................................................................... 3 3. Installation Architecture ........................................................................................ 3 4. Application Files ................................................................................................... 5 5. Application Shortcuts ............................................................................................ 7 6. Application Registry .............................................................................................. 9 7. Installation Location ............................................................................................ 10 8. Build Installation ................................................................................................. 11
第二部分:XML文件修改 ................................................................................................... 11 第三部分:自定义对话框 ..................................................................................................... 16 第四部分:安装windows服务 ............................................................................................ 18
一、 脚本方式 ............................................................................................................... 18 二、视图配置方式 ......................................................................................................... 21
添加Install Service组件 ........................................................................................ 21 添加Control Service组件 ...................................................................................... 24
第五部分:脚本编程 ............................................................................................................. 26
Setup.rul文件头部 ......................................................................................................... 27 OnFirstUIBefore ............................................................................................................. 28 OnFirstUIAfter ................................................................................................................ 31 SetTomportInfo ............................................................................................................... 34 完整脚本代码 ................................................................................................................. 36 第六部分:参考文章 ............................................................................................................. 43
I
注:我使用的是Installshield 2010 Premier Edition,安装后自行汉化,所以有部分截图有中文;
2010 SP1的官方下载地址: http://saturn.installshield.com/product/is/2010/domestic/premier/installShield2010.exe
第一部分:基本设置
新建Installscript MSI Project
打开Installshield 2010 Premier Edition,新建一个Installscript MSI Project,这种被称之为半脚本程序,因为兼具Basic Project基本类型和Installscript Project全脚本类型两者的优点。
选择类型为Windows Installer | InstallScript MSI Projcet,输入工程名,指定工程所在的文件夹。
界面会切换到Project Assistant,我们先从这里开始把工程的基本组件和基本文件建立好。
1
引导动作条
在Project Assistant界面的底部,会有一个引导动作条,在建立该工程的基本结构和文件时,我们都将在此界面进行操作,下文都将以“引导条”来指代这个引导动作条。
1. Application Information
这里输入:
公司名,公司名将会出现在Setup.exe的注解中 软件名,将会出现在安装过程的左上角标题栏上 版本号,软件版本 公司网址,必填
选择一个图标,这个图标会出现在“添加或删除程序”里,一般用默认的,当然可以替换成自己想要的图标。
2
2. Installation Requirement
这里选择对操作系统和一些软件的需求。根据自己需要来选择是否要求操作系统的版本,以及是否要求安装了某些软件。
3. Installation Architecture
这是个十分有用的设置,对于本文所用的分布式软件来说非常合适,分布式软件的每个组件可以设置为一个Feature,用户可以自由选择安装某些功能。
将选项Do you want to customize your Installation选择为Yes。 点击选中根节点Installation Architecture,点击New创建新的Feature,可以为每个Feature指定新名称。
还可以在Feature下创建子Feature,比如如果文档Feature下包括软件本身文档,和软件所需的运行环境的文档,那么可以创建两个子Feature,分别包含两种文档,用户在安装时就可以选择安装部分或者全部文档了。这里我们没有用到子Feature,用途和普通Feature一样。
3
这里,建立好所有Feature后,我们将切换到Installation Designer做一个设置
找到Installation Designer页面上左边导航树Organization | Features分支,你会看到这里Features都显示为原始的名称,而非我们改过的名字,因为Feature有Name和Display Name两种名称,我们刚才改的不过是Display Name,为了便于查看和使用,我们在这里把Name也改一下。
注意:Name不可以有空格,可以使用下划线。
4
4. Application Files
我们将在这里对安装路径进行微调,并且为每个Feature指定需要安装的文件 。
这里不想使用Program Files | Company Name | Product Name这个路径,想使用Program Files | Product Name,直接点击选中My Product Name[INSTALLDIR]拖动到ProgramFileFolder下,还可以直接将My Product Name 改成自己想要的文件夹名字,这里改为CKMH。
接下来,为每个Feature指定要安装的文件。
打开下拉列表,所有的Feature都在这里,按顺序来给每一个Feature建立文件夹,并且导入所需的文件。
选择一个Feature, 即ckmh,点击CKMH [INSTALLDIR]节点,右键点击,在菜单上选择New Folder来创建一个文件夹。
5
创建一个tomcat7文件夹,依次创建文件夹及子文件夹,然后为该Feature添加安装时该Feature要安装的文件。
点击选中要添加文件的文件夹,然后点击右下角的Add Files,然后添加文件 。 接下来为Feature添加文件夹,如果这个文件夹中的全部文件都为这个Feature所需。添加文件夹的好处在于只要文件夹位置和名称不变,那么文件夹里面的文件都是动态加载的,有多少加载多少,不用考虑文件名的改动带来的影响。
点击选中要添加文件夹的文件夹,然后点击右下角的Add Folders,然后添加文件夹。 选中文件夹,点击确定。
会询问你是否要使用动态文件链接,选择确定,好处就在于刚才上面所述。
6
显示了源文件夹,如果这个文件夹下有子文件夹,并且也需要一并添加进来的话,务必钩选Include subfolders选项。
这里还允许做一些简单设置来包含或者排除一些特定文件,支持通配符。 点击OK确定加入文件夹。
如法炮制为每个Feature建立文件夹,并且添加文件。 5. Application Shortcuts
接下来为可执行文件创建快捷方式。
点击New新建一个快捷方式
选择一个要建立快捷方式的Feature。
如果要建立快捷方式的程序为非.exe形式,请把Files Of选择选为All Files(*.*)格式。 程序安装目标路径设置在Program Files下,因此双击[ProgramFilesFolder]打开,层层点击进入。
7
这里要为startup.bat建立一个快捷方式。
选中快捷方式,点击Rename,并且为这个快捷方式改一个适当的名字。 Installshield可以自动监测到.exe文件的存在,自动生成快捷方式,用户只需要做一些适当修改即可。
免安装版Tomcat7的bin目录下有tomcat7.exe、tomcat7w.exe两个.exe文件,Installshield会自动为其创建快捷方式,这里已被移除,以下是创建好的快捷方式。
注意右边的几个选项。
Create shortcut in Start Menu,将在开始菜单里创建一个快捷方式。 Create shortcut on Desktop,将在桌面上创建一个快捷方式。 Use alternate shortcut Icon,替换快捷方式的图标。
Associate a file extension with the shortcut’s target,没用过,不知道什么意思。
再切换去Installation Designer,找到System Configuration | Shortcuts。
看到快捷方式在开始菜单中是以 公司名 | 软件名 | 快捷方式 这种形式存在的, 这里改成了如下设置 :
8
直接拖动CKMH文件夹往Program Menu(即开始菜单下的那个“所有程序”)下一塞即可,然后删除掉多余的Company Name文件夹。
可能刚才在Project Assistant界面有人已经注意到了左边栏上More Options下Create an uninstallation shortcut这个诱人的字样了。
如果选择了这种方式建立卸载快捷方式的话,会很沮丧地发现:
a) 似乎只有在安装某个feature的时候这个卸载快捷方式才会出现(当然,就是那个default feature,这种要命的feature形式决定了每个文件或者快捷方式都必须明确地归属到某个feature下),因此,当客户只选择了其他feature安装时,这个卸载方式不会出现,而他必须去“添加或卸载程序”里面去卸载。
b) 如果写脚本使得安装时会拷贝一些外部文件进来,那么这些文件在这种卸载方式下是删除不掉的。(如果确实想保存这些文件,可以在脚本里设置它们属性为permanent,这个属性可以保证什么卸载方式都不能删除你的这些文件)。
可以根据软件情况选择这种卸载快捷方式,或者采用后面脚本形式实现的卸载。
6. Application Registry
向注册表写键和键值。有需要的朋友可以查阅相关资料。
9
在脚本中有一段修改注册表的代码:
7. Installation Location
这个是用来设置安装包的语言。
这里没有改动,使用默认的简体中文。
10
8. Build Installation
选择要创建的安装映像类型。
至此,第一部分基本完成。如果是一些没有特别要求的安装包,这部分讲解的内容足够可以做一个基本的安装包了。
第二部分:XML文件修改
以修改 tomcat7\\conf\\server.xml 为例:
找到Installation Designer页面上左边导航树System Configuration | XML File Changes 节点,打开XML文件更改界面,
导入原始XML文件,右键点击根节点XML File,选择Import,打开导入向导界面,
11
点击Browse,选择需要导入的XML文件,Next>
12
选择XML元素,这里全选,点击Import,
点击 完成,即可看到导入的XML文件,选中导入的server.xml文件,右侧有配置项,
13
在General页签,指定该文件在安装文件中的位置,以及所属Feature;
左侧树展开server.xml文件,显示所有元素,以Connector元素的port属性为例,右侧General页签中,其默认值为8080,这里将其改为:[TOM_PORT],(带有括号)。
14
TOM_PORT是Behavior and Logic | Property Manager 下已经存在的属性。
注:属性定义必须大写,原因不知。
自定义安装界面(参考第三部分)获取用户输入的端口号,通过脚本为该属性赋值,进而改变XML文件中的值。
注:脚本中的数字‘1306’是自定义安装界面中输入框的Control Identifier。 以上为修改XML文件元素属性值,如果是修改元素内容,例如:修改dsn.xml文件中name元素的内容,在右侧Advanced页签中,选中Set element content,设置元素内容,在输入框中输入已定义的属性,如:[NAME],要加方括号,并通过脚本为该属性赋值。
15
第三部分:自定义对话框
找到Installation Designer页面上左边导航树User Interface | Dialogs 节点,打开Dialog视图。
1.在Dialogs视图中,右键All Dialog,选择新建对话框(New Dialog);
2.创建一个空白对话框,命名为Tomport.
16
3.双击MyDlg下的子项即可进入对话框的编辑模式;
注意:点击窗体,显示右侧属性 Resource Identifier需要根据需要自己定义,此值会在代码中使用到;需特别注意,为防止与其他的Id冲突,可设置较大一点,其后的ID会根据此ID自动递增。
4.工具栏有各种对话框组件,在工具栏上选择组件,然后在对话框界面上拖拉出相应组件,这里添加一个文本域和一个输入框,右侧可以修改组件属性,注意一下这里的Control Identifer属性值,后面脚本中会用到。
其Control Identifier值会根据Resource Identifier自增(窗体的Id叫 Resource Identifier,而组件的Id就称为Control Identifier)然后根据实际需要设计窗体布局。
其他的组件,如:上一步、下一步等,我是从其他已有的对话框中复制过来的,根据需要稍作修改,按钮的Control Identifier值要与其他对话框一样,否则不起作用,不清楚为什么。
注意:在dialog中必须添加一个Control Identifier为2的控件,否则点击右上角Close button的时候,是没有响应的。
17
界面部分已经完成,还需要写相应脚本,初始化对话框,给文本框赋值,或从文本框取值,具体脚本在第四部分》SetTomportInfo。
第四部分:安装windows服务
一、脚本方式
以Tomcat7注册为windows服务为例,将服务设置为开机启动,安装完成后启动该服务,脚本代码如图:
代码写在OnFirstUIAfter事件中,详细代码见第五章脚本编程》OnFirstUIAfter。
此处是利用免安装版Tomcat自带的service.bat批处理文件,注册服务,将Tomcat注册为windows服务,建议使用脚本方式,视图配置方式不太好用。
代码解释:
① szRegTomcat= INSTALLDIR ^ \"tomcat7\\\\bin\\\\service.bat\";
INSTALLDIR 表示安装路径,tomcat7\\bin\\service.bat为安装文件(根据实际安装文件目录修改),并且该文件一定要放到SUPPORTDIR 文件夹去,方法如下:
找到Installation Designer页面上左边导航树Behavior and Logic | Support Files / Billboards 节点,将service.bat文件放到Support Files/Language Independent下。
② nAddServer = LaunchAppAndWait(szRegTomcat,\"install\
执行批处理文件,第二个参数\"install\"为执行时的参数,表示安装服务,如果返回值小于0,表示安装失败。
③ MessageBox (\"添加Tomcat服务出错\消息弹框。
④ RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
szKeyRoot = \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\Tomcat7\" ;
18
RegDBSetKeyValueEx(szKeyRoot,\"Start\
修改注册表,服务安装后,启动类型默认为手动,修改注册表将启动类型改为自动,注册表位置HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tomcat7,将Start的值改为2(其中2为Automatic自动, 3为Manul手动, 4为Disabled禁用)。
⑤ ServiceStartService(\"Tomcat7\启动服务。 注:‘Tomcat7’为服务名,此名称为service.bat文件中的默认服务名,且与tomcat7\\bin目录下的tomcat7.exe、tomcat7w.exe显示名称一致,否则tomcat7.exe、tomcat7w.exe无法使用。
服务安装完成后,要为该服务添加一个控制组件,针对该服务配置组件安装完成和卸载时触发的事件,方法类似下面视图方式的添加Control Service组件,具体步骤如下:
① 导航树Organization -> Setup Design 节点,在左边工作区,右击服务所在feature,选择Component Wizard:
② 进入Wizard后,选择第2项:Let me select a type and define the component:
③ 设置组件名称,选择Control Service:
19
④ 选择Service is present on target system,输入上面安装的服务名称Tomcat7:
⑤ 组件安装完成后触发的事件,这里选择No event(do nothing)。如果脚本中没有写安装完成启动服务的代码,可以在这里配置,选择Start the service。
⑥ 设置在组件被卸载的时候触发的事件,这里设置停止并删除服务:
20
⑦ 设置安装和卸载时,进程的等待状态,选默认就可以了,下一步到完成。
二、视图配置方式
添加Install Service组件
① 找到Installation Designer页面上左边导航树Organization -> Components 节点:
② 在左边工作区,右击Components,选择Component Wizard:
③ 第一个对话框是要求建立feature的,这里点Yes就可以了,我选择了叫它在需要的时候自动生成feature;
注:如果要在已有的feature下新建Install Service组件或Control Service组件,①-③会
21
有不同,导航树Organization -> Setup Design 节点,在左边工作区,右击目标feature,选择Component Wizard,后续步骤相同。
④ 进入Wizard后,选择第2项:Let me select a type and define the component:
⑤ 设置组件名称,选择Install Service:
⑥ 在Service Executable里,选择要安装的windows service文件,在Services里,点Add按钮,添加这个文件包含的服务,这里写的服务名称要和程序里的对应:
22
⑦ 设置Display Name,按自己的服务设置Service Type:
⑧ 设置服务的启动方式,这里设置的是随机器启动:Automatically when the system starts up:
⑨ 下一步,下一步,设置服务启动出错的时候要做什么操作,后面的就一直下一步到完成:
23
注:如果要修改所加服务组件的‘可执行文件路径’,可在组件的信息界面更改‘destination’:
按这种方式安装Tomcat服务后,打开Tomcat7w.exe,会发现需要的配置信息都是空的,且服务无法启动,所以安装Tomcat服务推荐使用脚本方式。其他服务视情况而定。
添加Control Service组件
① 重复上面①-④;
② 设置组件名称,选择Control Service:
24
③ 选择该组件要控制的服务,这里直接选择Service is included in this setup,选择刚才添加的服务,就是说这个组件要控制的服务是刚才添加的组件里的服务:
④ 设置在组件安装完后要触发的事件,这里设置为启动服务:
⑤ 设置在组件被卸载的时候触发的事件,这里设置停止并删除服务:
25
⑥ 设置安装和卸载时,进程的等待状态,选默认就可以了,下一步到完成。
第五部分:脚本编程
找到Installation Designer页面上左边导航树Behavior and Logic | Installscript 节点,进入脚本编程视图。
下面就是脚本的主要实现:
脚步主要包括六个部分,即六个事件处理过程:
26
OnBegin OnEnd
OnFirstUIAfter OnFirstUIBefore OnMainUIAfter OnUninstall
这六个事件都是自动生成的,需要特殊的处理就在事件里面写脚步就可以了。
下面就是具体的脚本,全都在Setup.rul文件中,用到OnFirstUIAfter、OnFirstUIBefore,及自定义对话框出处理函数SetTomportInfo:
Setup.rul文件头部
//=========================================================================== // // File Name: Setup.rul // // Description: Blank setup main script file // // Comments: Blank setup is an empty setup project. If you want to // create a new project via. step-by step instructions use the // Project Assistant. // //=========================================================================== // Included header files ---------------------------------------------------- #include \"ifx.h\" // Note: In order to have your InstallScript function executed as a custom // action by the Windows Installer, it must be prototyped as an // entry-point function. // The keyword export identifies MyFunction() as an entry-point function. // The argument it accepts must be a handle to the Installer database. /* export prototype MyFunction(HWND); */ export prototype SetTomportInfo(BYREF STRING,BYREF STRING); 27
OnFirstUIBefore
此处定义安装界面需要展示的对话框,及对话框出现的顺序。 function OnFirstUIBefore() NUMBER nResult, nSetupType, nvSize, nUser; STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile, szOpt1, szOpt2, szBankPort; STRING szLicenseFile; LIST list, listStartCopy; BOOL bCustom, bLicenseAccepted, bRtf; 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)); SHELL_OBJECT_FOLDER = @PRODUCT_NAME; nSetupType = TYPICAL; Dlg_SdWelcome: szTitle = \"\"; szMsg = \"\"; nResult = SdWelcome(szTitle, szMsg);
28
if (nResult = BACK) goto Dlg_SdWelcome; szTitle = \"\"; svName = \"\"; svCompany = \"\"; Dlg_SdLicense2Ex: szTitle = \"\"; szOpt1 = \"\"; szOpt2 = \"\"; szLicenseFile = SUPPORTDIR^\"License.txt\";//License文件 bLicenseAccepted = FALSE; bRtf = FALSE; //MessageBox (szLicenseFile,MB_YESNO); nResult = SdLicense2Ex (szTitle, szOpt1, szOpt2, szLicenseFile, bLicenseAccepted, bRtf); if (nResult = BACK) goto Dlg_SdWelcome; Dlg_Tomport: szMsg = \"\"; szBankPort=\"8080\"; nResult=SetTomportInfo(szMsg,szBankPort); //使用新创建的界面 if(nResult=BACK) goto Dlg_SdLicense2Ex; Dlg_SdAskDestPath: nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0); if (nResult = BACK) goto Dlg_Tomport;
29
Dlg_SdStartCopy: szTitle = \"\"; szMsg = \"\"; listStartCopy = ListCreate( STRINGLIST ); //The following is an example of how to add a string(svName) to a list(listStartCopy). //eg. ListAddString(listStartCopy,svName,AFTER); nResult = SdStartCopy2( szTitle, szMsg ); ListDestroy(listStartCopy); if (nResult = BACK) then goto Dlg_SdAskDestPath; endif; // setup default status Enable(STATUSEX); return 0; end; 代码解释:
Dlg_SdWelcome:安装欢迎界面; Dlg_SdLicense2Ex:协议声明界面;
Dlg_Tomport:此为自定义界面,配置Tomcat服务访问端口,默认为8080; Dlg_SdAskDestPath:选择安装路径; Dlg_SdStartCopy:开始安装界面。
30
OnFirstUIAfter
创建卸载快捷方式,注册windows服务,修改服务启动类型,启动服务,设置安装结束界面。
//--------------------------------------------------------------------------- // OnFirstUIAfter // 安装完成后,点完成前发生的事件 // //--------------------------------------------------------------------------- function OnFirstUIAfter() STRING szfilename,szFolder ,szmsg1,szmsg2; STRING szRegTomcat; STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2; STRING szKeyRoot; NUMBER bStartService, nresult; NUMBER bvOpt1, bvOpt2, nAddServer; begin ShowObjWizardPages(NEXT); szTitle = \"\"; szMsg1 = \"\"; szMsg2 = \"\"; szOpt1 = \"\"; szOpt2 = \"\"; bvOpt1 = FALSE; bvOpt2 = FALSE; //创建卸载快捷方式 szfilename = UNINSTALL_STRING +\" /UNINSTALL\"; nresult = StrFind(szfilename,\".exe\"); if nresult >=0 then StrSub(szmsg1,szfilename,0,nresult + 4); StrSub(szmsg2,szfilename,nresult + 4,200); LongPathToQuote(szmsg1, FALSE ); LongPathToQuote(szmsg2, FALSE );
31
szfilename = \"\\\"\" + szmsg1 + \"\\\"\" +szmsg2; endif; AddFolderIcon(FOLDER_PROGRAMS^\"CKMH\NDIR,\"\ //注册windows服务 szRegTomcat= INSTALLDIR ^ \"tomcat7\\\\bin\\\\service.bat\"; // MessageBox (\"添加Tomcat:\"+szRegTomcat,SEVERE); nAddServer = LaunchAppAndWait(szRegTomcat,\"install\ if(nAddServer<0) then MessageBox (\"添加Tomcat服务出错\ endif; if(nAddServer>=0) then //修改服务启动类型为自动 RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); //设置注册表函数默认值 szKeyRoot = \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\Tomcat7\" ; //HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tomcat7 RegDBSetKeyValueEx(szKeyRoot,\"Start\修改 Start 值为 2 ,其中2为Automatic, 3为Manul, 4为Disabled //启动服务 ServiceStartService(\"Tomcat7\ endif; //安装完成 对话框 if ( BATCH_INSTALL ) then SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 ); else SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bvOpt1 , bvOpt2 ); endif; end;
代码解释:
************************************************************************* szfilename = UNINSTALL_STRING +\" /UNINSTALL\";
参数一:UNINSTALL_STRING这个静态变量指向的就是安装程序,也就是setup.exe,不过指向的位置不是源盘里的setup.exe,而是C:\\Program Files\\InstallShield Installation Information\\{0D9DF66A-44E5-4754-A522-2AD6C9D5CDBE}\\setup.exe;Installshield创建的
32
安装文件在安装时总会在这个文件夹里创建对应信息,一长串数字型序列码就是安装程序的Product ID。利用这个setup.exe就可以进行反安装;
参数二:/UNINSTALL,告诉程序启动这个setup.exe时为非安装状态,即修复、重新安装和卸载状态。
因此,这个字符串的值应该是这种形式: C:\\Program Files\\InstallShield Installation Information\\{0D9DF66A-44E5-4754-A522-2AD6C9D5CDBE}\\setup.exe -runfromtemp -l0x0409 /UNINSTALL
************************************************************************* nresult = StrFind(szfilename,\".exe\");
寻找到“.exe”这个字符串在szfilename这个字符串中的位置。 Help里对这个函数的描述如下: StrFind (szString, szFindMe);
参数一:szString,被查找的源字符串 参数二:szFindMe,要查找的字符串
返回值为要查找的字符串在源字符串中的位置,如果返回值小于0,则说明源字符串中找不到要查找的字符串;
************************************************************************* StrSub(szmsg1,szfilename,0,nresult + 4); StrSub(szmsg2,szfilename,nresult + 4,200);
如果要查找的字符串存在,那么源字符串就是正确的;这两句语句就对源字符串进行截断,得到想要的子串。
szmsg1应该为C:\\Program Files\\InstallShield Installation Information\\{0D9DF66A-44E5-4754-A522-2AD6C9D5CDBE}\\setup.exe;
而szmsg2应该为 -runfromtemp -l0x0409 /UNINSTALL;
Help里的解释如下:
StrSub ( svSubStr, szString, nStart, nLength ); 参数一:svSubStr返回的结果字符串 参数二:szfilename源字符串
参数三:开始截断的位置。如果指定的位置大于整个被解析的字符串长度,则返回一个空字串。
参数四:结束截断的位置。如果指定的位置大于整个被解析的字符串长度,则默认为结束截断的位置是字符串的结尾处。
************************************************************************* LongPathToQuote(szmsg1, FALSE ); LongPathToQuote(szmsg2, FALSE );
这两句的作用是对上面解析出的两个子串脱去引号。
33
************************************************************************ szfilename = \"\\\"\" + szmsg1 + \"\\\"\" +szmsg2;
拼凑出正确的可执行文件的长文件名,带路径,包含扩展名;
************************************************************************* AddFolderIcon(FOLDER_PROGRAMS^\"CKMH\,\"\
添加一个快捷方式到 开始 | 所有程序 | CKMH 下,快捷方式名称为 Uninstall_CKMH。
这个快捷方式运行的时候,出现界面和在安装完毕后再次运行安装程序出现的界面相同,选择Remove即可进行卸载。
这个卸载不会把程序运行时产生的文件卸载掉,比如日志文件、配置信息文件等;会把安装目录中所有从安装程序中安装的文件都卸载掉,包括安装时从外部拷贝的文件。利用Project Assistant创建的卸载快捷方式则无法卸载掉安装时从外部拷贝的文件。
注册windows服务的代码在第四部分》脚本方式中有解释,在此不再赘述。
************************************************************************* SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 ); SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bvOpt1 , bvOpt2 );
安装结束对话框。
SetTomportInfo
自定义对话框的处理函数,需要在Setup.rul文件头部添加一行代码: export prototype SetTomportInfo(BYREF STRING,BYREF STRING);
其中用到的Resource Identifier、Control Identified需要根据自定义对话框设置修改。 function SetTomportInfo(szMsg,svPort) STRING szDlg, szTemp; BOOL bDone; NUMBER nId, nMessage, nTemp, nSdDialog, nSdCustomRegisterUserEx; HWND hwndDlg, hwndControl; begin szDlg = \"Tomport\";//对话框名称 nSdDialog = 22222;//自定义对话框的Resource Identifier // 确保一般的初始化完成
34
if (!bSdInit) then SdInit( ); endif; //初始化Dialog if (EzDefineDialog( szDlg, \"\ return -1; endif; // 在对话框中循环,直到用户选择一个标准按钮 bDone = FALSE; while (!bDone) //Dialog界面中每一个操作均会触发该事件,返回控件的Control Identified nId = WaitOnDialog( szDlg ); switch(nId) case DLG_INIT://第一次打开该界面时执行 if( szMsg != \"\" ) then SdSetStatic( szDlg, SD_STA_MSG, szMsg ); endif; //将参数设置到控件中,即显示默认值 CtrlSetText(szDlg,1306,svPort);//1306为端口输入框的Control Identified hwndDlg = CmdGetHwndDlg( szDlg ); SdGeneralInit( szDlg, hwndDlg, STYLE_BOLD, szSdProduct ); //EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd); case 1306: //输入框改变时执行 nMessage = CtrlGetSubCommand( szDlg ); if( nMessage = EDITBOX_CHANGE ) then CtrlGetText( szDlg, 1306, svPort );//从安装界面获取值 MsiSetProperty (ISMSI_HANDLE,\"TOM_PORT\为属性赋值 endif; //EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd); case NEXT: //下一步按钮 nId = NEXT; bDone = TRUE; //MessageBox (nId,MB_YESNO); case BACK: //上一步按钮 nId = BACK; bDone = TRUE; //MessageBox (BACK,MB_YESNO); case DLG_ERR: SdError( -1, \"Tomport\" );
35
nId = -1; bDone = TRUE; //MessageBox (DLG_ERR,MB_YESNO); case DLG_CLOSE: SdCloseDlg( hwndDlg, nId, bDone ); //MessageBox (DLG_CLOSE,MB_YESNO); default: // check standard handling if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then bDone = TRUE; endif; endswitch; endwhile; EndDialog( szDlg ); ReleaseDialog( szDlg ); SdUnInit( ); return nId; end; 完整脚本代码
//=========================================================================== // // File Name: Setup.rul // // Description: Blank setup main script file // // Comments: Blank setup is an empty setup project. If you want to // create a new project via. step-by step instructions use the // Project Assistant. // //=========================================================================== // Included header files ---------------------------------------------------- #include \"ifx.h\"
36
// Note: In order to have your InstallScript function executed as a custom // action by the Windows Installer, it must be prototyped as an // entry-point function. // The keyword export identifies MyFunction() as an entry-point function. // The argument it accepts must be a handle to the Installer database. /* export prototype MyFunction(HWND); */ export prototype SetTomportInfo(BYREF STRING,BYREF STRING); function OnFirstUIBefore() NUMBER nResult, nSetupType, nvSize, nUser; STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile, szOpt1, szOpt2, szBankPort; STRING szLicenseFile; LIST list, listStartCopy; BOOL bCustom, bLicenseAccepted, bRtf; 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)); SHELL_OBJECT_FOLDER = @PRODUCT_NAME; nSetupType = TYPICAL;
37
Dlg_SdWelcome: szTitle = \"\"; szMsg = \"\"; nResult = SdWelcome(szTitle, szMsg); if (nResult = BACK) goto Dlg_SdWelcome; szTitle = \"\"; svName = \"\"; svCompany = \"\"; Dlg_SdLicense2Ex: szTitle = \"\"; szOpt1 = \"\"; szOpt2 = \"\"; szLicenseFile = SUPPORTDIR^\"License.txt\";//License文件 bLicenseAccepted = FALSE; bRtf = FALSE; //MessageBox (szLicenseFile,MB_YESNO); nResult = SdLicense2Ex (szTitle, szOpt1, szOpt2, szLicenseFile, bLicenseAccepted, bRtf); if (nResult = BACK) goto Dlg_SdWelcome; Dlg_Tomport: szMsg = \"\"; szBankPort=\"8080\"; nResult=SetTomportInfo(szMsg,szBankPort); //使用新创建的界面 if(nResult=BACK) goto Dlg_SdLicense2Ex;
38
Dlg_SdAskDestPath: nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0); if (nResult = BACK) goto Dlg_Tomport; Dlg_SdStartCopy: szTitle = \"\"; szMsg = \"\"; listStartCopy = ListCreate( STRINGLIST ); //The following is an example of how to add a string(svName) to a list(listStartCopy). //eg. ListAddString(listStartCopy,svName,AFTER); nResult = SdStartCopy2( szTitle, szMsg ); ListDestroy(listStartCopy); if (nResult = BACK) then goto Dlg_SdAskDestPath; endif; // setup default status Enable(STATUSEX); return 0; end;
39
//--------------------------------------------------------------------------- // OnFirstUIAfter // 安装完成后,点完成前发生的事件 // //--------------------------------------------------------------------------- function OnFirstUIAfter() STRING szfilename,szFolder ,szmsg1,szmsg2; STRING szRegTomcat; STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2; STRING szKeyRoot; NUMBER bStartService, nresult; NUMBER bvOpt1, bvOpt2, nAddServer; begin ShowObjWizardPages(NEXT); szTitle = \"\"; szMsg1 = \"\"; szMsg2 = \"\"; szOpt1 = \"\"; szOpt2 = \"\"; bvOpt1 = FALSE; bvOpt2 = FALSE; //创建卸载快捷方式 szfilename = UNINSTALL_STRING +\" /UNINSTALL\"; nresult = StrFind(szfilename,\".exe\"); if nresult >=0 then StrSub(szmsg1,szfilename,0,nresult + 4); StrSub(szmsg2,szfilename,nresult + 4,200); LongPathToQuote(szmsg1, FALSE ); LongPathToQuote(szmsg2, FALSE ); szfilename = \"\\\"\" + szmsg1 + \"\\\"\" +szmsg2; endif;
40
AddFolderIcon(FOLDER_PROGRAMS^\"CKMH\NDIR,\"\ //注册windows服务 szRegTomcat= INSTALLDIR ^ \"tomcat7\\\\bin\\\\service.bat\"; // MessageBox (\"添加Tomcat:\"+szRegTomcat,SEVERE); nAddServer = LaunchAppAndWait(szRegTomcat,\"install\ if(nAddServer<0) then MessageBox (\"添加Tomcat服务出错\ endif; if(nAddServer>=0) then //修改服务启动类型为自动 RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); //设置注册表函数默认值 szKeyRoot = \"SYSTEM\\\\CurrentControlSet\\\\Services\\\\Tomcat7\" ; //HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tomcat7 RegDBSetKeyValueEx(szKeyRoot,\"Start\修改 Start 值为 2 ,其中2为Automatic, 3为Manul, 4为Disabled //启动服务 ServiceStartService(\"Tomcat7\ endif; //安装完成 对话框 if ( BATCH_INSTALL ) then SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 ); else SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bvOpt1 , bvOpt2 ); endif; end; //自定义端口 对话框 function SetTomportInfo(szMsg,svPort) STRING szDlg, szTemp; BOOL bDone; NUMBER nId, nMessage, nTemp, nSdDialog, nSdCustomRegisterUserEx; HWND hwndDlg, hwndControl; begin szDlg = \"Tomport\";//对话框名称 nSdDialog = 22222;//自定义对话框的Resource Identifier // 确保一般的初始化完成 if (!bSdInit) then
41
SdInit( ); endif; //初始化Dialog if (EzDefineDialog( szDlg, \"\ return -1; endif; // 在对话框中循环,直到用户选择一个标准按钮 bDone = FALSE; while (!bDone) //Dialog界面中每一个操作均会触发该事件,返回控件的Control Identified nId = WaitOnDialog( szDlg ); switch(nId) case DLG_INIT://第一次打开该界面时执行 if( szMsg != \"\" ) then SdSetStatic( szDlg, SD_STA_MSG, szMsg ); endif; //将参数设置到控件中,即显示默认值 CtrlSetText(szDlg,1306,svPort);//1306为端口输入框的Control Identified hwndDlg = CmdGetHwndDlg( szDlg ); SdGeneralInit( szDlg, hwndDlg, STYLE_BOLD, szSdProduct ); //EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd); case 1306: //输入框改变时执行 nMessage = CtrlGetSubCommand( szDlg ); if( nMessage = EDITBOX_CHANGE ) then CtrlGetText( szDlg, 1306, svPort ); MsiSetProperty (ISMSI_HANDLE,\"TOM_PORT\ endif; //EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd); case NEXT: //下一步按钮 nId = NEXT; bDone = TRUE; //MessageBox (nId,MB_YESNO); case BACK: //上一步按钮 nId = BACK; bDone = TRUE; //MessageBox (BACK,MB_YESNO); case DLG_ERR: SdError( -1, \"Tomport\" ); nId = -1;
42
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- gamedaodao.com 版权所有 湘ICP备2022005869号-6
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务