日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

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

發布時間:2025/3/21 asp.net 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET完整打包卸载更新攻略(By Installshield 2010)【转】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

-

前言

前陣子做了一個有關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可看到以上界面。

二、填寫產品信息

?

填寫產品的基本信息(包括產品名稱,安裝語言,產品的安裝版本,產品編碼……)

三、選擇文件源

?

選擇文件源,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;


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 Identifier

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);
?????????????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.config
string?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文件,詳情請按F1

?

5、修改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語句也是調用dososql.exe文件

5、屏蔽控制面板里添加刪除程序的那個安裝信息



九、結束語

首先感謝Installshield技術交流群(158107742)的群主海洋女神,Kevin,單車,棕橙藍綠……還有其他群里的朋友們。排名不分前后

如果有看不懂或者不明白的可以給我留言或者加qq群跟大家交流交流,如果想了解更專業的Installshield技術,可以閱讀以下的博客:

?

1.論壇http://www.appinstall.cn/

2.入門http://home.cnblogs.com/Cindy_weiwei

3.提高http://home.cnblogs.com/installshield

?

附:由于部分資源文件涉及公司機密,僅能提供自定義對話框和數據庫操作的腳本資源:/Files/magicchaiy/腳本.rar

轉載于:https://www.cnblogs.com/yangzhx/p/3632504.html

總結

以上是生活随笔為你收集整理的ASP.NET完整打包卸载更新攻略(By Installshield 2010)【转】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。