在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言 前阵子做了一个有关Installshield的OA 打包安装程序,用的版本Installshield 2010-Premier,具体功能的内容如下: 1、OA采用的是asp.net(C#)开发 2、动态发布到IIS虚拟目录(采用自定义对话框) 3、附加,分离,删除数据库 4、动态修改web.config 5、完美卸载 6、更新包制作 【安装】首先准备一个发布好的aspnet网站,然后在web.config插入标签,在app_data文件夹放入数据库文件。安装的时候会自动把文件copy到目标机器,在使用dos命令将app_data里面的文件附加到数据库,根据用户填写的数据库信息替换web.config的标签…… 【更新】更新包的思路也很简单,在安装的时候会把用户填写的数据库信息存到注册表(数据库服务器,用户名,密码,虚拟目录,安装路径),用了这些信息,那么更新的时候直接把文件copy到用户安装时选择的路径就可以了,如果有数据库相关的更新,则可以使用dos命令执行数据库文件(.sql),如果有web.config的更新,则再一次动态替换web.config的标签即可。 【卸载】网站的卸载就是删除文件,分离和删除数据库,删除注册表相关键值,删除虚拟目录 接下来让我们一步一步来实现,篇幅可能有点长,请大家 pay patience,Let’s go 一、新建项目
选择All Types下面的InstallScript MSI Project,填写产品名称,保存路径,点击OK
Installation Designer安装设计,点击进去可看到产品的信息,安装脚本,安装界面等 切换到Installation Designer可看到以上界面。 二、填写产品信息
填写产品的基本信息(包括产品名称,安装语言,产品的安装版本,产品编码……) 三、选择文件源
选择文件源,在DefaultComponents下面的files点击右键,选择Dynamic File Linking选择文件源(将文件源填充到components,多个components组成一个features)
点击 New Link弹出Dynamic File Link Settings对话框,点击Browse选择文件夹,然后点击OK,在点击左边对话框的确定,则完成文件源的设置
定位到Setup Design选项,可看到右边窗口有DefaultFeature和DefaultComponents 1个Feature(功能)可以拆分为多个Components(组件),1:N 1个Components可以绑定一个文件夹或者文件,1:N 在Defaultfeature右键选择Associate Components,弹出Component的列表,选择然后点击OK按钮则可以将该components添加到feature下面。 四、设置文件夹权限
功能Feature关联完Component后则可以在Application Data下面的files and folders看到关联过来的文件夹信息,可以对其进行局部调整。也可以对文件夹进行权限控制,权限设置如下:
选中文件夹,右键点击Properties属性,则弹出以下属性窗口
点击Permissions弹出以下界面
在空白处点击右键选择New,则弹出以下界面
设置文件夹的权限,点击OK完成
五、Installshield Script 默认的脚本没有任何东西,只有一句 #include "ifx.h",必须点击右边的安装函数才出来脚本。 InstallScript脚本的语法类似于C,也类似于VBScript,可以调用VB的代码。也可以调用dos命令,也可以调用exe。
选择 Before Move Data 阶段的函数 OnFirstUIBefore,可出来安装过程中对话框的代码,代码如下: function OnFirstUIBefore() NUMBER nResult, nSetupType, nvSize, nUser; STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile; STRING szLicenseFile; BOOL bCustom, bIgnore1, bIgnore2; 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)); // Added in InstallShield 15 - Show an appropriate error message if // -removeonly is specified and the product is not installed. if( REMOVEONLY ) then Disable( DIALOGCACHE ); szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST ); SdSubstituteProductInfo( szMsg ); MessageBox( szMsg, SEVERE ); abort; endif; nSetupType = TYPICAL; Dlg_SdWelcome: szTitle = ""; szMsg = ""; nResult = SdWelcome(szTitle, szMsg); if (nResult = BACK) goto Dlg_SdWelcome; szTitle = ""; svName = ""; svCompany = ""; Dlg_SdRegisterUser: szMsg = ""; szTitle = ""; nResult = SdRegisterUser( szTitle, szMsg, svName, svCompany ); if (nResult = BACK) goto Dlg_SdWelcome; Dlg_SetupType: szTitle = ""; szMsg = ""; nResult = SetupType2(szTitle, szMsg, "", nSetupType, 0); if (nResult = BACK) then goto Dlg_SdRegisterUser; else nSetupType = nResult; if (nSetupType != CUSTOM) then nvSize = 0; FeatureCompareSizeRequired(MEDIA, INSTALLDIR, nvSize); if (nvSize != 0) then MessageBox(szSdStr_NotEnoughSpace, WARNING); goto Dlg_SetupType; endif; bCustom = FALSE; goto Dlg_SQL; else bCustom = TRUE; endif; endif; Dlg_SdAskDestPath: nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0); if (nResult = BACK) goto Dlg_SetupType; Dlg_SdFeatureTree: szTitle = ""; szMsg = ""; if (nSetupType = CUSTOM) then nResult = SdFeatureTree(szTitle, szMsg, INSTALLDIR, "", 2); if (nResult = BACK) goto Dlg_SdAskDestPath; endif; Dlg_SQL: nResult = OnSQLLogin( nResult ); if( nResult = BACK ) then if (!bCustom) then goto Dlg_SetupType; else goto Dlg_SdFeatureTree; endif; endif; Dlg_SdStartCopy: szTitle = ""; szMsg = ""; nResult = SdStartCopy2( szTitle, szMsg ); if (nResult = BACK) then goto Dlg_SQL;; endif; // Added in IS 2009 - Set appropriate StatusEx static text. SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI ) ); // setup default status Enable(STATUSEX); return 0; end;
若要引用其他的对话框,则要从dialog source里面调出对话框函数
六、Dialog对话框
对话框选项位于User Interface(用户体验,简称UI)下面的Dialog(对话框)选项 鼠标悬停在对话框名称,右键,选择Edit,可看到对话框的相关信息(布局,控件,属性……Control Identifier是唯一标识列),可以修改对话框的布局和信息。
Skin则是对话框的皮肤,选中皮肤,点击Select应用该皮肤。
七、一个完整的ASP.NET打包程序 1、前言 在了解了Installshield 2010 的一些基本设置和熟悉操作界面后,给大家演示一个完整的ASP.NET打包程序,ASP.NET的安装与部署比较简单,主要是把网站发布到IIS,附加数据库,配置数据库信息(包括数据库用户,密码,服务器),修改web.config配置文件。主要功能有: ● 手动选择安装目录 ● 创建和设置IIS虚拟目录 ● 动态附加分离数据库 ● 自动修改配置文件 ● 完美卸载 2、创建IIS虚拟目录 2.1、自定义创建虚拟目录对话框 由于Installshield自身没有操作IIS的功能,那么就要借助外部程序或者windowsAPI,用程序配置 IIS 所用到的“技术”无非是 ADSI 或者 WMI 提供的组件服务程序。可以通过 Windows Host Script 来执行 JScript 或者 VBScript 脚本,也可以在 VB/Delphi 这类快速开发工具开发程序来调用,甚至可以通过浏览器中运行的 JavaScript/JScript/VBScript 以及 IIS 运行的 ASP 来调用。因为支持 IDispatch 接口,所以可以后期绑定地通过 CreateObject 或者 GetObject 方式来获取 ADSI/WMI 的特定接口。那么我们这里就简单地利用adsi来操作IIS。 由于Installshield自身没有创建虚拟目录的窗口,那么我们就简单的自己做一个自定义的窗口,窗口很简单,就只有一个文本框,用于输入虚拟目录的名称。制作过程如下:
首先先All Dialogs那里右键,弹出菜单,选择New Dialog
新建对话框向导
对话框有多种类型: Blank Dialog 空对话框,该对话框什么都没有,连上一步,下一步的按钮都没有 NewScriptBasedDialog 普通基于脚本的对话框,带基本按钮 NewSkinnableDialog 带皮肤功能的对话框,带基本按钮
如果弹出冲突页面,直接点击SkipAll就行了。
添加完皮肤对话框后,界面如上,现在就可以对对话框进行编辑,修改对话框标题,按钮的文字,字体大小,摆置方式等。最重要的是甚至对话框的Resource identifier,这是对话框的唯一标识列。 那么现在对话框已经添加完成了,那么如何在安装的过程中显示该对话框呢? 每个对话框都有一个构造函数,那么只有调用该对话框的构造函数就行了,接下来请看怎么编写对话框的构造函数(详情按F1)。 在DefineDialog ( szDialogName, hInstance, szDLLName,nDialogID, szDialogID, nReserved, hwndOwner, lMsgLevel ); 这个函数里,最主要的参数就是第四个nDialogID(对话框ID),也就是对话框Resource identifier属性的值。那么对话框构造函数就可以这样写: szDialogName = "SelectVirDialog"; hInstance = 0; szDLLName = ""; nSdDialog = "13001" szDialog = ""; hwndParent = 0; nResult = DefineDialog (szDialogName, hInstance, szDLLName, nSdDialog, szDialog, hwndParent, HWND_INSTALL, DLG_MSG_STANDARD|DLG_CENTERED); if ( nResult = DLG_ERR ) then bDone = TRUE; return -1; endif; 这里设置了一个名字为SelectVirDialog的对话框,对话框ID为13001,其他参数可以为空或为0。那么有了构造函数,那么在Setup.rul里面就可以调用构造函数,使用对话框了。 一般为了方便管理,每个对话框都会配置一个对话框的脚本。脚本里面也就是构造函数和点击按钮的业务处理
//选择虚拟目录 Dlg_SdSelectVirtual: szTitle=""; szMsg=""; nResult=SdSelectVirtual(szTitle,szMsg); if(nResult=BACK) then goto Dlg_SdAskDestPath; endif; if(nResult=NEXT && !MAINTENANCE) then goto Dlg_SQL; endif; SdSelectVirtual也就是一个构造函数,里面封装了DefineDialog 函数和业务处理。返回的是按钮ID,BACK和NEW都是枚举值。 对话框其实处于一种死循环状态,只靠goto语句来跳出循环。具体出来的对话框界面如下:
那么如果获取用户输入的值呢? 跟对话框的原理一样,每一个控件也是有一个唯一标识列的(Control Identifier) 设置控件的值CtrlSetText(szDialogName,1204,"A8"); szDialogName是对话框的名称,跟DefineDialog第一个参数相对应。 最后一个参数则是设置和获取填充的值或变量。 // Initialize the indicator used to control the while loop. bDone = FALSE; // Loop until done. while (!bDone) // Display the dialog and return the next dialog event. nId = WaitOnDialog( szDlg); // Respond to the event. switch(nId) case DLG_INIT: CtrlSetText(szDialogName,1204,"A8"); // No initialization is required for this example. case NEXT: nId = NEXT; bDone = TRUE; CtrlGetText(szDialogName,1204,svVituralDir); //将路径写到注册表 nRootKey = HKEY_CURRENT_USER; szKey = "Software\\A8"; szClass=""; //更换注册表根目录 if (RegDBSetDefaultRoot (nRootKey) < 0) then MessageBox ("First call to RegDBSetDefaultRoot failed.", SEVERE); endif; //创建注册表项 if (RegDBKeyExist (szKey) < 0) then if (RegDBCreateKeyEx (szKey, szClass) < 0) then MessageBox ("RegDBCreateKeyEx failed.", SEVERE); endif; endif; //创建键值对[虚拟目录,目标目录] RegDBSetKeyValueEx (szKey, "VirDir", REGDB_STRING, svVituralDir,-1); RegDBSetKeyValueEx (szKey, "TargetDir", REGDB_STRING, TARGETDIR,-1); nExists=CreateWebSite(svVituralDir); if(nExists==0) then nId=0; bDone=FALSE; else nId=NEXT; bDone=TRUE; endif; case BACK: nId = BACK; bDone = TRUE; case DLG_ERR: SdError( -1, "MyDefineDialog" ); nId = -1; bDone = TRUE; case DLG_CLOSE: SdCloseDlg( hwndDlg, nId, bDone ); default: if(SdIsStdButton( nId ) && SdDoStdButton( nId )) then bDone = TRUE; endif; endswitch; endwhile; 2.2、创建虚拟目录(使用ADSI) 设置好界面,获取到用户输入的虚拟目录名称,接下来就是创建虚拟目录了。 第一步:获取IIS的Default站点 set objW3SVC = CoGetObject("IIS://localhost/W3SVC/1/Root",""); 第二步:创建虚拟目录 set objVirDir=objW3SVC.Create("IISWebVirtualDir",virtrualDir);//virtrualDir是变量 objVirDir.Path = TARGETDIR; objVirDir.AccessRead = TRUE; objVirDir.AccessScript = TRUE; objVirDir.AppCreate(TRUE); objVirDir.SetInfo(); 详细代码请参考SdSelectVirtual.rul的CreateWebSite函数 3、填写数据库信息 3.1、自定义数据库对话框 数据库的对话框也需要自定义,在上面已经介绍过自定义对话框的制作方法,数据库对话框界面如下: 填写服务器信息,默认是localhost或者.都可以 填写用户名,默认一般是sa 填写密码,默认是****** 3.2、验证数据库信息
bDone = FALSE; // Loop until done. while (!bDone) // Display the dialog and return the next dialog event. nId = WaitOnDialog( szDlg); // Respond to the event. switch(nId) case DLG_INIT: CtrlSetText(szDialogName,REX_CTRL_ID_SERVER,"localhost"); CtrlSetText(szDialogName,REX_CTRL_ID_USER,""); CtrlSetText(szDialogName,REX_CTRL_ID_PWD,""); // No initialization is required for this example. case NEXT: nId = NEXT; bDone = TRUE; CtrlGetText(szDialogName,REX_CTRL_ID_SERVER,svServer); CtrlGetText(szDialogName,REX_CTRL_ID_USER,svUser); CtrlGetText(szDialogName,REX_CTRL_ID_PWD,svPwd); Server=svServer; User=svUser; Pwd=svPwd; //判断数据库链接是否成功(0代表链接失败,1代表链接成功) szWaitTxt="正在检查数据库用户名和密码"; SdShowMsg (szWaitTxt, TRUE); Delay(2); |
请发表评论