ASP.NET完整打包卸载更新攻略(By Installshield 2010)(转载)

发布时间:2017-2-26 6:57:14 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"ASP.NET完整打包卸载更新攻略(By Installshield 2010)(转载)",主要涉及到ASP.NET完整打包卸载更新攻略(By Installshield 2010)(转载)方面的内容,对于ASP.NET完整打包卸载更新攻略(By Installshield 2010)(转载)感兴趣的同学可以参考一下。

前言前阵子做了一个有关Installshield的OA 打包安装程序,用的版本Installshield 2010-Premier,具体功能的内容如下:1、OA采用的是asp.net(C#)开发2、动态发布到IIS虚拟目录(采用自定义对话框)3、附加,分离,删除数据库4、动态修改web.config5、完美卸载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可看到以上界面。二、填写产品信息填写产品的基本信息(包括产品名称,安装语言,产品的安装版本,产品编码……)三、选择文件源 选择文件源,在DefaultComponents下面的files点击右键,选择Dynamic File Linking选择文件源(将文件源填充到components,多个components组成一个features)点击 New Link弹出Dynamic File Link Settings对话框,点击Browse选择文件夹,然后点击OK,在点击左边对话框的确定,则完成文件源的设置 定位到Setup Design选项,可看到右边窗口有DefaultFeature和DefaultComponents1个Feature(功能)可以拆分为多个Components(组件),1:N1个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;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对话框 对话框选项位于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");获取控件的值CtrlGetText(szDialogName,1204,svVituralDir);1204是控件的Control IdentifierszDialogName是对话框的名称,跟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);             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);                 endif;                                     //创建注册表项                   if (RegDBKeyExist (szKey) < 0) then                     if (RegDBCreateKeyEx (szKey, szClass) < 0) then                         MessageBox ("RegDBCreateKeyEx failed.", SEVERE);                     endif;                 endif;                    //添加到注册表                 RegDBSetKeyValueEx (szKey, "Server", REGDB_STRING, Server,-1);                RegDBSetKeyValueEx (szKey, "User", REGDB_STRING, User,-1);                RegDBSetKeyValueEx (szKey, "Pwd", REGDB_STRING, Pwd,-1);            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; DB_CheckConnection 这个函数用于验证当前用户输入的数据库信息是否正确,有关数据库的相关操作位于database.rul文件。如果数据库的信息填写无误,那么把数据库信息写到注册表,方便以后升级使用。4、附加数据库在执行复制文件到目标机器后,点击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的全局变量  endif;end;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,Pwd; //全局变量附加数据库是调用了dos命令的osql.exe,代码如下://创建数据库function CreateDataBase(svSQLsvr,svSQLusr,svSQLpwd)     STRING szCmdLine,szWaitTxt,szCommandLine;     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);     endif;      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);     endif;     SdShowMsg (szWaitTxt,FALSE);      //打开浏览器浏览制定的网页        szCommandLine = ProgramFilesFolder ^ "Internet Explorer\\iexplore.exe";    LaunchAppAndWait(szCommandLine, "http://localhost/"+svVituralDir+"/login/login.aspx", NOWAIT);       //修改配置文件    ConfigurateSql();     end; 在这里使用了LaunchAppAndWait调用exe文件,详情请按F15、修改Web.Config文件修改Web.Config文件也是在文件拷贝到目标机器的完成阶段实现。第一步:定标签在Web.Config文件里为每一个要替换的节点定下一个注释标签  <connectionStrings>    <!--#constring1#--><add name="abc" connectionString="database=abc;server=.;uid=sa;pwd=123" providerName="System.Data.SqlClient"/>  </connectionStrings><!--#constring1#-->则是一个注释标签第二步:定位行数根据标签就可以找到该标签下面那一个节点,代码看GetLineNum函数//从上往下搜索某文件下面的字符串,并返回该字符串所在的行数function NUMBER GetLineNum(szFileName,szSearchStr,isContinue)string svReturnLine;NUMBER nvLineNumber,nvResult;begin     nvResult = FileGrep (szFileName, szSearchStr, svReturnLine, nvLineNumber,isContinue);     switch(nvResult)             case FILE_NOT_FOUND:             // Report error; then abort.             MessageBox( szFileName + " not found.", WARNING);             abort;         case FILE_LINE_LENGTH:             // Report error; then abort.             MessageBox (szFileName + "lines too long.", WARNING);             abort;         case OTHER_FAILURE:             // Report error; then abort.             MessageBox (szFileName + "Unknown failure on call to FileGrep.", WARNING);             abort;     endswitch;     return (nvLineNumber+1);end ;第三步:替换该行数据使用FileInsertLine函数可以替换文件中的某一行。            //替换webconfig里面链接字符串,使用GetLineNum注意最后一个参数,从头开始找还是继续上次往下找            nvLineNum=GetLineNum(ConFullDir,sConTag1,CONTINUE);            if(FileInsertLine(ConFullDir,ConString1,nvLineNum,REPLACE)<0) then            MessageBox ("FileInsertLine failed.", SEVERE);             endif; 6、完美卸载安装过程已经完成,接下来看如何完美卸载程序(删除文件,分离数据库,删除虚拟目录)选择Installscript,找到你要卸载的Feature,默认是DefaultFeature,选择卸载事件,UnInstalling(卸载前)和UnInstalled(卸载后)第一步:分离数据库因为卸载界面已经脱离了安装的生命周期,那么所有变量都被回收了,要获取数据库信息只能从注册表获取(安装的时候已写进了注册表)//更换注册表根目录    if (RegDBSetDefaultRoot (nRootKey) < 0) then          MessageBox ("First call to RegDBSetDefaultRoot failed.", INFORMATION);     endif;          //从注册表取数据库和虚拟目录相关信息    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);     endif;    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);              endif;     endif; 删除虚拟目录一样使用了ADSI第三步:停止数据库服务和删除注册表键值     //停止数据库服务SQLSERVERAGENT,MSSQLSERVER    szCmdLine = " stop SQLSERVERAGENT";        if(LaunchAppAndWait("sc", szCmdLine,LAAW_OPTION_NOWAIT | LAAW_OPTION_HIDDEN)<0) then       MessageBox ("无法停止数据库服务--SQLSERVERAGENT,请手动关闭该服务",SEVERE);     endif;       szCmdLine=" stop MSSQLSERVER";    if(LaunchAppAndWait("sc", szCmdLine,LAAW_OPTION_NOWAIT | LAAW_OPTION_HIDDEN) <0) then        MessageBox ("无法停止数据库服务--MSSQLSERVER,请手动关闭该服务",SEVERE);     endif;            //删除完删除注册表      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 szCmdLine;begin    //删除后重新启动数据库服务--MSSQLSERVER    szCmdLine=" start MSSQLSERVER";    if(LaunchAppAndWait("sc", szCmdLine,LAAW_OPTION_NOWAIT | LAAW_OPTION_HIDDEN) <0) then        MessageBox ("无法启动数据库服务--MSSQLSERVER,请手动启动该服务",SEVERE);     endif;                    //可能删除不干净,手动执行删除文件夹    if(ExistsDir(TARGETDIR)=EXISTS ) then           if(DeleteDir(TARGETDIR,ALLCONTENTS) < 0) then            MessageBox("删除失败",SEVERE)  ;        endif;    endif;end;启动数据库服务,删除文件夹。整个卸载过程完成。八、更新包制作1、前言更新包也是一个独立的InstallScript MSI Project,只不过相比于安装包少了一些步骤,更新包的原理就是从注册表读出安装时写进的信息,如:数据库服务器,用户名,密码,虚拟目录,安装路径。界面略……直接跳过选择安装目录那个对话框,因为获取了注册表的那个安装路径了。代码如下:Dlg_SdStartCopy:    szTitle = "";    szMsg   = "";    nResult = SdStartCopy2( szTitle, szMsg );                if (nResult = BACK) then       goto Dlg_SQL;;    endif;          //获取注册表的目标路径    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;end;2、选择更新文件方法跟安装的时候是一样的3、修改Product Code,每次更新都要换一个Code,要不会出现(修复,卸载,重装的操作界面)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,sqlRoot;    string targetDir,server,user,pwd;    NUMBER nRootKey;begin    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);         endif;        else         MessageBox ("找不到更新的sql文件,请联系供销商!",SEVERE);      endif;endif;    end;执行更新的sql语句也是调用dos的osql.exe文件5、屏蔽控制面板里添加删除程序的那个安装信息九、结束语首先感谢Installshield技术交流群(158107742)的群主海洋女神,Kevin,单车,棕橙蓝绿……还有其他群里的朋友们。排名不分前后如果有看不懂或者不明白的可以给我留言或者加qq群跟大家交流交流,如果想了解更专业的Installshield技术,可以阅读以下的博客:

上一篇:Silverlight实例教程 - Out of Browser在线更新和Silent安装
下一篇:Spring 中Hibernate session 打开和关闭总结

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。