installshield 限量版可以打包asp.net 微信小程序程序吗?

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)ASP.NET完整打包卸载更新攻略(By Installshield 2010)【转】
时间: 19:49:47
&&&& 阅读:435
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-
前阵子做了一个有关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
点击OK后出来这个界面Project Assistant 项目助手,点击进去可看到有些简单描述项目的选项
Installation Designer安装设计,点击进去可看到产品的信息,安装脚本,安装界面等&
切换到Installation& Designer可看到以上界面。
二、填写产品信息
填写产品的基本信息(包括产品名称,安装语言,产品的安装版本,产品编码……)
三、选择文件源
选择文件源在下面的点击右键选择选择文件源将文件源填充到多个组成一个
点击&New Link弹出Dynamic File Link
Settings对话框,点击Browse选择文件夹,然后点击OK,在点击左边对话框的确定,则完成文件源的设置
定位到Setup Design选项,可看到右边窗口有DefaultFeature和DefaultComponents
1个Feature(功能)可以拆分为多个Components(组件),1:N
1个Components可以绑定一个文件夹或者文件,1:N&
在右键选择,弹出的列表,选择然后点击按钮则可以将该添加到下面。
四、设置文件夹权限
功能Feature关联完Component后则可以在Application Data下面的files and
folders看到关联过来的文件夹信息,可以对其进行局部调整。也可以对文件夹进行权限控制,权限设置如下:
选中文件夹,右键点击Properties属性,则弹出以下属性窗口
点击Permissions弹出以下界面
在空白处点击右键选择New,则弹出以下界面
设置文件夹的权限,点击OK完成&
五、Installshield Script
默认的脚本没有任何东西,只有一句&#include "ifx.h",必须点击右边的安装函数才出来脚本。
InstallScript脚本的语法类似于C,也类似于VBScript,可以调用VB的代码。也可以调用dos命令,也可以调用exe。
选择阶段的函数&,可出来安装过程中对话框的代码,代码如下:
function&OnFirstUIBefore()&&&&NUMBER&nResult,&nSetupType,&nvSize,&nU&&&&STRING&szTitle,&szMsg,&szQuestion,&svName,&svCompany,&szF&&&&STRING&szLicenseF&&&&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&);&&&&&&&&&&&&&&&&&&&&nSetupType&=&TYPICAL;&&&&Dlg_SdWelcome:&&&&szTitle&=&"";&&&&szMsg&&&=&"";&&&&nResult&=&SdWelcome(szTitle,&szMsg);&&&&if&(nResult&=&BACK)&goto&Dlg_SdW&&&&&&&&szTitle&&&=&"";&&&&svName&&&&=&"";&&&&svCompany&=&"";Dlg_SdRegisterUser:&&&&szMsg&=&"";&&&&szTitle&=&"";&&&&nResult&=&SdRegisterUser(&szTitle,&szMsg,&svName,&svCompany&);&&&&if&(nResult&=&BACK)&goto&Dlg_SdWDlg_SetupType:&&&&szTitle&=&"";&&&&szMsg&&&=&"";&&&&nResult&=&SetupType2(szTitle,&szMsg,&"",&nSetupType,&0);&&&&if&(nResult&=&BACK)&then&&&&&&&&goto&Dlg_SdRegisterU&&&&else&&&&&&&&nSetupType&=&nR&&&&&&&&if&(nSetupType&!=&CUSTOM)&then&&&&&&&&&&&&nvSize&=&0;&&&&&&&&&&&&FeatureCompareSizeRequired(MEDIA,&INSTALLDIR,&nvSize);&&&&&&&&&&&&if&(nvSize&!=&0)&then&&&&&&&&&&&&&&&&&&&&&&MessageBox(szSdStr_NotEnoughSpace,&WARNING);&&&&&&&&&&&&&&&&goto&Dlg_SetupT&&&&&&&&&&&&&&&&&&&&&&&&bCustom&=&FALSE;&&&&&&&&&&&&goto&Dlg_SQL;&&&&&&&&else&&&&&&&&&&&&bCustom&=&TRUE;&&&&&&&&&&&&&&&&Dlg_SdAskDestPath:&&&&&&&&&&&&nResult&=&SdAskDestPath(szTitle,&szMsg,&INSTALLDIR,&0);&&&&if&(nResult&=&BACK)&goto&Dlg_SetupTDlg_SdFeatureTree:&&&&&szTitle&&&&=&"";&&&&szMsg&&&&&&=&"";&&&&if&(nSetupType&=&CUSTOM)&then&&&&&&&&nResult&=&SdFeatureTree(szTitle,&szMsg,&INSTALLDIR,&"",&2);&&&&&&&&if&(nResult&=&BACK)&goto&Dlg_SdAskDestP&&&&&&Dlg_SQL:&&&&nResult&=&OnSQLLogin(&nResult&);&&&&if(&nResult&=&BACK&)&then&&&&&&&&if&(!bCustom)&then&&&&&&&&&&&&goto&Dlg_SetupT&&&&&&&&&&&&else&&&&&&&&&&&&goto&Dlg_SdFeatureT&&&&&&&&&&&&Dlg_SdStartCopy:&&&&szTitle&=&"";&&&&szMsg&&&=&"";&&&&nResult&=&SdStartCopy2(&szTitle,&szMsg&);&&&&&&&&&&&&&&&&&&&&if&(nResult&=&BACK)&then&&&&&&&goto&Dlg_SQL;;&&&&&&&&//&Added&in&IS&2009&-&Set&appropriate&StatusEx&static&text.&&&&SetStatusExStaticText(&SdLoadString(&IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI&)&);&&&&//&setup&default&status&&&&Enable(STATUSEX);&&&&&return&0;
Dlg_SdWelcome:&&& 欢迎对话框Dlg_SdRegisterUser&&
注册用户对话框Dlg_SetupType&&&&&&
安装类型对话框Dlg_SdAskDestPath
选择安装目录对话框Dlg_SdFeatureTree&&&&&&&
功能树对话框Dlg_SQL&& sql相关对话框Dlg_SdStartCopy
复制文件对话框这几个是系统默认的对话框,所有对话框的生命周期基于Setup.rul脚本,也就是说需要在Setup.Rul里面设置对话框的相关脚本信息和调用对话框的构造函数。系统默认的对话框脚本都包含在#include
"ifx.h"头文件里面,如果是自定义的对话框则【后面会提到】需要引用相关对话框的脚本。
若要引用其他的对话框,则要从dialog source里面调出对话框函数
六、Dialog对话框
对话框选项位于(用户体验,简称)下面的(对话框)选项
鼠标悬停在对话框名称,右键,选择Edit,可看到对话框的相关信息(布局,控件,属性……Control
Identifier是唯一标识列),可以修改对话框的布局和信息。
则是对话框的皮肤,选中皮肤,点击应用该皮肤。
七、一个完整的打包程序
在了解了的一些基本设置和熟悉操作界面后,给大家演示一个完整的打包程序,的安装与部署比较简单主要是把网站发布到,附加数据库,配置数据库信息(包括数据库用户,密码,服务器),修改配置文件。主要功能有:
●&&&&&手动选择安装目录
●&&&&&创建和设置虚拟目录
●&&&&&动态附加分离数据库
●&&&&&自动修改配置文件
●&&&&&完美卸载
、创建虚拟目录
、自定义创建虚拟目录对话框
由于自身没有操作的功能,那么就要借助外部程序或者,用程序配置所用到的“技术”无非是或者提供的组件服务程序。可以通过来执行或者脚本,也可以在这类快速开发工具开发程序来调用,甚至可以通过浏览器中运行的以及运行的来调用。因为支持接口,所以可以后期绑定地通过或者方式来获取的特定接口。那么我们这里就简单地利用来操作。
由于Installshield自身没有创建虚拟目录的窗口,那么我们就简单的自己做一个自定义的窗口,窗口很简单,就只有一个文本框,用于输入虚拟目录的名称。制作过程如下:
首先先那里右键,弹出菜单,选择
新建对话框向导
对话框有多种类型:
空对话框,该对话框什么都没有,连上一步,下一步的按钮都没有
普通基于脚本的对话框,带基本按钮
带皮肤功能的对话框,带基本按钮
如果弹出冲突页面,直接点击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;&&&&&&
&这里设置了一个名字为SelectVirDialog的对话框,对话框ID为13001,其他参数可以为空或为0。那么有了构造函数,那么在Setup.rul里面就可以调用构造函数,使用对话框了。
一般为了方便管理,每个对话框都会配置一个对话框的脚本。脚本里面也就是构造函数和点击按钮的业务处理
//选择虚拟目录&&&Dlg_SdSelectVirtual:&&&&&&&
szTitle="";&&&&&&&
szMsg="";&&&&&&&
nResult=SdSelectVirtual(szTitle,szMsg);&&&&&&&&if(nResult=BACK)
then&&&&&&&&&&&&&goto&Dlg_SdAskDestP&&&&&&&&&&&
&&&&&&&&if(nResult=NEXT
&& !MAINTENANCE)
then&&&&&&&&&&&&goto&Dlg_SQL;&&&&&&&
SdSelectVirtual也就是一个构造函数,里面封装了DefineDialog&函数和业务处理。返回的是按钮ID,BACK和NEW都是枚举值。
对话框其实处于一种死循环状态,只靠goto语句来跳出循环。具体出来的对话框界面如下:
那么如果获取用户输入的值呢?
跟对话框的原理一样,每一个控件也是有一个唯一标识列的()
设置控件的值获取控件的值是控件的
是对话框的名称,跟第一个参数相对应。
最后一个参数则是设置和获取填充的值或变量。
&//&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);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//创建注册表项&&&&&&&&&&&&&&&if&(RegDBKeyExist&(szKey)&&&0)&then&&&&&&&&&&&&&&&&&if&(RegDBCreateKeyEx&(szKey,&szClass)&&&0)&then&&&&&&&&&&&&&&&&&&&&&MessageBox&("RegDBCreateKeyEx&failed.",&SEVERE);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//创建键值对[虚拟目录,目标目录]&&&&&&&&&&&&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;&&&&&&&&&&&&&&&&&&&&&&&&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;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2.2、创建虚拟目录(使用ADSI)
设置好界面,获取到用户输入的虚拟目录名称,接下来就是创建虚拟目录了。
第一步:获取IIS的Default站点
set objW3SVC = CoGetObject("IIS://localhost/W3SVC/1/Root","");
第二步:创建虚拟目录
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=svS&&&&&&&&&&&&&&&&&&&&&&&&&User=svU&&&&&&&&&&&&&&&&&&&&&&&&&Pwd=svP&&&&&&&&&&&&&&//判断数据库链接是否成功(0代表链接失败,1代表链接成功)&&&&&&&&&&&&&&szWaitTxt="正在检查数据库用户名和密码";&&&&&&&&&&&&&&SdShowMsg&(szWaitTxt,&TRUE);&&&&&&&&&&&&&Delay(2);&&&&&&&&&&&&&SdShowMsg&(szWaitTxt,&FALSE);&&&&&&&&&&&&&&if(DB_CheckConnection(Server,"SQL&Server",User,Pwd)!=1)&then&&&&&&&&&&&&&&&&nId=0;&&&&&&&&&&&&&&&&bDone=FALSE;&&&&&&&&&&&&&&&&&&MessageBox&("数据库用户名或者密码错误,请重新输入",&WARNING);&&&&&&&&&&&&&&&&CtrlSetText(szDialogName,REX_CTRL_ID_USER,"");&&&&&&&&&&&&&&&&CtrlSetText(szDialogName,REX_CTRL_ID_PWD,"");&&&&&&&&&&&&else&&&&&&&&&&&&&&&&nId=NEXT;&&&&&&&&&&&&&&&&bDone=TRUE;&&&&&&&&&&&&&&&&&&&&&//将路径写到注册表&&&&&&&&&&&&&&&&nRootKey&=&HKEY_CURRENT_USER;&&&&&&&&&&&&&&&&szKey&=&"Software\\A8";&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//更换注册表根目录&&&&&&&&&&&&&&&&if&(RegDBSetDefaultRoot&(nRootKey)&&&0)&then&&&&&&&&&&&&&&&&&&&&&&MessageBox&("First&call&to&RegDBSetDefaultRoot&failed.",&SEVERE);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//创建注册表项&&&&&&&&&&&&&&&&&&&if&(RegDBKeyExist&(szKey)&&&0)&then&&&&&&&&&&&&&&&&&&&&&if&(RegDBCreateKeyEx&(szKey,&szClass)&&&0)&then&&&&&&&&&&&&&&&&&&&&&&&&&MessageBox&("RegDBCreateKeyEx&failed.",&SEVERE);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//添加到注册表&&&&&&&&&&&&&&&&&RegDBSetKeyValueEx&(szKey,&"Server",&REGDB_STRING,&Server,-1);&&&&&&&&&&&&&&&&RegDBSetKeyValueEx&(szKey,&"User",&REGDB_STRING,&User,-1);&&&&&&&&&&&&&&&&RegDBSetKeyValueEx&(szKey,&"Pwd",&REGDB_STRING,&Pwd,-1);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&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;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
DB_CheckConnection&这个函数用于验证当前用户输入的数据库信息是否正确,有关数据库的相关操作位于database.rul文件。
如果数据库的信息填写无误,那么把数据库信息写到注册表,方便以后升级使用。
、附加数据库
在执行复制文件到目标机器后,点击Finish(完成)按钮会触发函数onend
//---------------------------------------------------------------------------//&OnEnd////&The&OnEnd&event&is&called&at&the&end&of&the&setup.&This&event&is&not//&called&if&the&setup&is&aborted.//---------------------------------------------------------------------------function&OnEnd()begin&if(!MAINTENANCE)then//ConfigurateSql();CreateDataBase(Server,User,Pwd);//Server,User,Pwd为SdCreateSql.rul的全局变量&&
Server,User,Pwd都是全局变量,把变量定义到最顶部跟#include同级
#include&"Ifx.h"&&#include&"database.rul"&#define&REX_DIALOG_ID&13003#define&REX_CTRL_ID_SERVER&1209&//服务器#define&REX_CTRL_ID_USER&1207&//用户名#define&REX_CTRL_ID_PWD&1208&//密码export&prototype&SdCreateSql(string,&string);&//构造函数//prototype&CreateDataBase(STRING,STRING,string);//创建数据库prototype&AlterConfigure(string);//修改web.configstring&Server,User,P&//全局变量
附加数据库是调用了dos命令的osql.exe,代码如下:
//创建数据库function&CreateDataBase(svSQLsvr,svSQLusr,svSQLpwd)&&&&&STRING&szCmdLine,szWaitTxt,szCommandL&&&&&begin&&&&&//A8数据库&&&&szWaitTxt="&正在创建A8数据库.";&&&&&SdShowMsg&(szWaitTxt,&TRUE);&&&&&Delay(2);&&&&&szCmdLine&=&"/U&"+svSQLusr+"&/P&"+svSQLpwd+"&/S&"+svSQLsvr+"&/Q&\"EXEC&&sp_attach_db&&@dbname&&=&&N‘A8‘,@filename1&&=&N‘"+TARGETDIR&^"App_Data\\A8.mdf‘,@filename2&&=&N‘"+TARGETDIR&^"App_Data\\A8_log.ldf‘\"";&&&&&if&(LaunchAppAndWait("osql.exe",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&&&0)&then&&&&&&&&&MessageBox&("数据库创建失败!请确您的系统中已安装&Microsoft&SQL&Server&2000.&如仍无法解决,请联系系统供应商!",SEVERE);&&&&&&&&&&&SdShowMsg&(szWaitTxt,FALSE);&&&&&&szWaitTxt="&正在优化系统数据库.";&&&&&SdShowMsg&(szWaitTxt,&TRUE);&&&&&Delay(2);&&&&&szCmdLine&=&"/U&"+svSQLusr+"&/P&"+svSQLpwd+"&/S&"+svSQLsvr+"&/Q&\"use&A8&;&exec&sp_updatestats\"";&&&&&if&(LaunchAppAndWait("osql.exe",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&&&0)&then&&&&&MessageBox&("数据库优化失败!您可以在&sql查询分析器中执行&use&dlbj&;&exec&sp_updatestats&完成!",SEVERE);&&&&&&&&&&SdShowMsg&(szWaitTxt,FALSE);&&&&&&//打开浏览器浏览制定的网页&&&&&&&&szCommandLine&=&ProgramFilesFolder&^&"Internet&Explorer\\iexplore.exe";&&&&LaunchAppAndWait(szCommandLine,&"http://localhost/"+svVituralDir+"/login/login.aspx",&NOWAIT);&&&&&&&//修改配置文件&&&&ConfigurateSql();&&&&&&
在这里使用了调用文件,详情请按
5、修改Web.Config文件
修改Web.Config文件也是在文件拷贝到目标机器的完成阶段实现。
第一步:定标签
在Web.Config文件里为每一个要替换的节点定下一个注释标签
& &connectionStrings&&&&
&!--#constring1#--&&add name="abc"
connectionString="database=server=.;uid=pwd=123"
providerName="System.Data.SqlClient"/&&
&/connectionStrings&
&!--#constring1#--&则是一个注释标签
第二步:定位行数
根据标签就可以找到该标签下面那一个节点,代码看GetLineNum函数
//从上往下搜索某文件下面的字符串,并返回该字符串所在的行数function&NUMBER&GetLineNum(szFileName,szSearchStr,isContinue)string&svReturnLNUMBER&nvLineNumber,nvRbegin&&&&&nvResult&=&FileGrep&(szFileName,&szSearchStr,&svReturnLine,&nvLineNumber,isContinue);&&&&&switch(nvResult)&&&&&&&&&&&&&case&FILE_NOT_FOUND:&&&&&&&&&&&&&//&Report&&then&abort.&&&&&&&&&&&&&MessageBox(&szFileName&+&"&not&found.",&WARNING);&&&&&&&&&&&&&&&&&&&&&&case&FILE_LINE_LENGTH:&&&&&&&&&&&&&//&Report&&then&abort.&&&&&&&&&&&&&MessageBox&(szFileName&+&"lines&too&long.",&WARNING);&&&&&&&&&&&&&&&&&&&&&&case&OTHER_FAILURE:&&&&&&&&&&&&&//&Report&&then&abort.&&&&&&&&&&&&&MessageBox&(szFileName&+&"Unknown&failure&on&call&to&FileGrep.",&WARNING);&&&&&&&&&&&&&&&&&&&&&&&return&(nvLineNumber+1);end&;
第三步:替换该行数据
使用FileInsertLine函数可以替换文件中的某一行。
&&&&&&&&&&&&//替换webconfig里面链接字符串,使用GetLineNum注意最后一个参数,从头开始找还是继续上次往下找&&&&&&&&&&&&nvLineNum=GetLineNum(ConFullDir,sConTag1,CONTINUE);&&&&&&&&&&&&if(FileInsertLine(ConFullDir,ConString1,nvLineNum,REPLACE)&0)&then&&&&&&&&&&&&MessageBox&("FileInsertLine&failed.",&SEVERE);&&&&&&&&&&&&&&
、完美卸载
安装过程已经完成,接下来看如何完美卸载程序(删除文件,分离数据库,删除虚拟目录)
选择Installscript,找到你要卸载的Feature,默认是DefaultFeature,选择卸载事件,UnInstalling(卸载前)和UnInstalled(卸载后)
第一步:分离数据库
因为卸载界面已经脱离了安装的生命周期,那么所有变量都被回收了,要获取数据库信息只能从注册表获取(安装的时候已写进了注册表)
//更换注册表根目录&&&&if&(RegDBSetDefaultRoot&(nRootKey)&&&0)&then&&&&&&&&&&MessageBox&("First&call&to&RegDBSetDefaultRoot&failed.",&INFORMATION);&&&&&&&&&&&&&&&//从注册表取数据库和虚拟目录相关信息&&&&RgVirDir=GetReg("VirDir");&&&&RgServer=GetReg("Server");&&&&RgUser=GetReg("User");&&&&RgPwd=GetReg("Pwd");&&&&&&//分离A8数据库&&&&&&&szWaitTxt="正在分离A8数据库";&&&&SdShowMsg&(szWaitTxt,&TRUE);&&&&&&Delay(2);&&&&szCmdLine&=&"/U&"+RgUser+"&/P&"+RgPwd+"&/S&"+RgServer+"&/Q&\"EXEC&&sp_detach_db&‘A8‘";&&&&&&if(&&&&LaunchAppAndWait("osql.exe",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&&0)&then&&&&&&&&MessageBox&("数据库分离失败!请确您的系统中已安装&Microsoft&SQL&Server&2000.&如仍无法解决,请联系系统供应商!",SEVERE);&&&&&&&&&SdShowMsg&(szWaitTxt,&FALSE);&&
GetReg是一个自定义函数,参数则是注册表的键名
分离数据库还是使用dos命令下的osql.exe
删除数据库文件只能先分离,不然会有数据库质疑的字样
第二步:删除虚拟目录
&//删除虚拟目录&&&&&set&objW3SVC&=&CoGetObject("IIS://localhost/W3SVC/1/Root",&"");//获取Default站点&&&&&&&&if(IsObject(objW3SVC))&then&&&&&&&&if(IsObject(&CoGetObject("IIS://localhost/W3SVC/1/Root/"+RgVirDir+"","")))&then&&&&&&&&&&&&&&&&&szWaitTxt="正在删除"+RgVirDir+"虚拟目录";&&&&&&&&&&&&&&&&&&&Delay(2);&&&&&&&&&&&&&&&&SdShowMsg&(szWaitTxt,&TRUE);&&&&&&&&&&&&&&&&&&&&&&objW3SVC.Delete("IIsWebVirtualDir",RgVirDir)&;&&&&&&&&&&&&&&&&SdShowMsg&(szWaitTxt,&FALSE);&&&&&&&&&&&&&&&&&&&&
删除虚拟目录一样使用了ADSI
第三步:停止数据库服务和删除注册表键值
&&&&&//停止数据库服务SQLSERVERAGENT,MSSQLSERVER&&&&szCmdLine&=&"&stop&SQLSERVERAGENT";&&&&&&&&if(LaunchAppAndWait("sc",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&0)&then&&&&&&&MessageBox&("无法停止数据库服务--SQLSERVERAGENT,请手动关闭该服务",SEVERE);&&&&&&&&&&&&szCmdLine="&stop&MSSQLSERVER";&&&&if(LaunchAppAndWait("sc",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&&0)&then&&&&&&&&MessageBox&("无法停止数据库服务--MSSQLSERVER,请手动关闭该服务",SEVERE);&&&&&&&&&&&&&&&&&//删除完删除注册表&&&&&&DelReg(KEY);
DelReg是自定义函数,参数是注册表的键
第四步:删除文件夹和启动数据库服务(在UnInstalled卸载后触发)
//---------------------------------------------------------------------------//&The&UnInstalled&event&is&sent&after&the&feature&DefaultFeature//&is&uninstalled.//&sented&after&delete&defaultFeature//---------------------------------------------------------------------------&export&prototype&DefaultFeature_UnInstalled();function&DefaultFeature_UnInstalled()&string&szCmdLbegin&&&&//删除后重新启动数据库服务--MSSQLSERVER&&&&szCmdLine="&start&MSSQLSERVER";&&&&if(LaunchAppAndWait("sc",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&&0)&then&&&&&&&&MessageBox&("无法启动数据库服务--MSSQLSERVER,请手动启动该服务",SEVERE);&&&&&&&&&&&&&&&&&&&&&&&&&//可能删除不干净,手动执行删除文件夹&&&&if(ExistsDir(TARGETDIR)=EXISTS&)&then&&&&&&&&&&&if(DeleteDir(TARGETDIR,ALLCONTENTS)&&&0)&then&&&&&&&&&&&&MessageBox("删除失败",SEVERE)&&;&&&&&&&&&&&&
启动数据库服务,删除文件夹。
整个卸载过程完成。
八、更新包制作
更新包也是一个独立的InstallScript MSI
Project,只不过相比于安装包少了一些步骤,更新包的原理就是从注册表读出安装时写进的信息,如:数据库服务器,用户名,密码,虚拟目录,安装路径。界面略……
直接跳过选择安装目录那个对话框,因为获取了注册表的那个安装路径了。代码如下:
Dlg_SdStartCopy:&&&&szTitle&=&"";&&&&szMsg&&&=&"";&&&&nResult&=&SdStartCopy2(&szTitle,&szMsg&);&&&&&&&&&&&&&&&&if&(nResult&=&BACK)&then&&&&&&&goto&Dlg_SQL;;&&&&&&&&&&&&&&//获取注册表的目标路径&&&&TARGETDIR=&GetReg("TargetDir");&&&&&&&&//&Added&in&IS&2009&-&Set&appropriate&StatusEx&static&text.&&&&SetStatusExStaticText(&SdLoadString(&IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI&)&);&&&&//&setup&default&status&&&&Enable(STATUSEX);&&&&&return&0;
2、选择更新文件
方法跟安装的时候是一样的
修改,每次更新都要换一个
4、运行sql语句
假如有更新sql语句,将需要运行的sql语句整理成一个文件
//---------------------------------------------------------------------------//&OnEnd////&The&OnEnd&event&is&called&at&the&end&of&the&setup.&This&event&is&not//&called&if&the&setup&is&aborted.//---------------------------------------------------------------------------function&OnEnd()&&&&&&STRING&szKey,&szClass,&szMsg,&szTitle,szCmdLine,sqlR&&&&string&targetDir,server,user,&&&&NUMBER&nRootKbegin&&&&if(!MAINTENANCE)then&&&&targetDir=&&GetReg("TargetDir");&&&&server=&GetReg("Server");&&&&user=&GetReg("User");&&&&pwd=&GetReg("Pwd");&&&&sqlRoot=&targetDir+"sqlFile.sql"&;&&&&LongPathToQuote(sqlRoot&,TRUE);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(Is(FILE_EXISTS,sqlRoot))&then&&&&&&&&szCmdLine&=&"/U&"+user+"&/P&"+pwd+"&/S&"+server+"&/i&"+sqlRoot+"";&&&&&&&&&if&(LaunchAppAndWait("osql.exe",&szCmdLine,LAAW_OPTION_NOWAIT&|&LAAW_OPTION_HIDDEN)&&&0)&then&&&&&&&&&&&&&MessageBox&("运行sql更新文件时失败,请联系供销商!",SEVERE);&&&&&&&&&&&&&&&&&else&&&&&&&&&MessageBox&("找不到更新的sql文件,请联系供销商!",SEVERE);&&&&&&&&&&
执行更新的语句也是调用的文件
5、屏蔽控制面板里添加删除程序的那个安装信息
九、结束语
首先感谢Installshield技术交流群()的群主海洋女神,Kevin,单车,棕橙蓝绿……还有其他群里的朋友们。排名不分前后
如果有看不懂或者不明白的可以给我留言或者加qq群跟大家交流交流,如果想了解更专业的Installshield技术,可以阅读以下的博客:
1.论坛http://
附:由于部分资源文件涉及公司机密,仅能提供自定义对话框和数据库操作的脚本资源:标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://www.cnblogs.com/yangzhx/p/3632504.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!

我要回帖

更多关于 asp程序设计 的文章

 

随机推荐