Net程序打包安裝與卸載制作 ——問(wèn)題描述(一) 項(xiàng)目已將近完工,怎樣將你的程序打包,包裝成一個(gè)完美的安裝程序呢?今天我將我個(gè)人使用.Net制作打包程序的經(jīng)驗(yàn)分享給大家,不足之處還希望大家 能夠給予指正。面對(duì)對(duì).Net平臺(tái)開發(fā)出來(lái)的程序,它的運(yùn)行對(duì)系統(tǒng)環(huán)境要求有點(diǎn)高,需要.Net Framework的支持,所以首先面對(duì)的問(wèn)題是怎樣將.Net Framework1.1或2.0安裝在一臺(tái)沒(méi)有以前沒(méi)有裝過(guò)的機(jī)子上。以下是我在打包過(guò)程中需要解決的問(wèn)題: 一.怎樣將.NET程序部署到?jīng)]有安裝_NET Framwork的機(jī)器上? 解決了以上的問(wèn)題后,基本上能夠滿足你的安裝項(xiàng)目需要了吧?好了廢話少說(shuō),現(xiàn)在我們馬上來(lái)動(dòng)手制作。 .Net程序打包安裝與卸載制作 ——怎樣將.Net程序部署到?jīng)]有安裝.Net Framwork的機(jī)器上?(二) 部署在.Net 平臺(tái)下開發(fā)的應(yīng)用程序,需要安裝安裝對(duì)應(yīng)版本的.Net Framwork,而Vsual Studio 2003并沒(méi)有提供一起打包的功能,所以這一點(diǎn)估計(jì)大多開發(fā)者都感覺(jué)不是太好,那如何將.Net Framework安裝部署到客戶機(jī)上呢? Config.ini — 安裝配置文件 Config的文件內(nèi)容如下: Settings.ini文件內(nèi)容如下: 這種方法能夠很簡(jiǎn)單的將.Net Framwork與你的應(yīng)用程序一起打包到安裝程序中,并且自動(dòng)檢測(cè)客機(jī)上的是否安裝過(guò).Net Framework,然后運(yùn)行安裝。相信大家一定能夠喜歡這個(gè)插件。 .Net程序打包安裝與卸載制作 ——怎樣在打包程序中自動(dòng)安裝SQL Server數(shù)據(jù)庫(kù)(三)? 1、創(chuàng)建安裝項(xiàng)目“Setup1”安裝項(xiàng)目 在“文件”菜單上指向“添加項(xiàng)目”,然后選擇“新建項(xiàng)目”。 在“添加新項(xiàng)目”對(duì)話框中,選擇“項(xiàng)目類型”窗格中的“安裝和部署項(xiàng)目”,然后選擇“模板”窗格中的“安裝項(xiàng)目”。在“名稱”框中鍵入 “setup1”。 單擊“確定”關(guān)閉對(duì)話框。 項(xiàng)目被添加到解決方案資源管理器中,并且文件系統(tǒng)編輯器打開。 在“屬性”窗口中,選擇 ProductName 屬性,并鍵入”億萬(wàn)電器成套報(bào)價(jià)系統(tǒng)”。 2、在安裝項(xiàng)目中創(chuàng)建安裝程序類(install.cs)。 添加創(chuàng)建數(shù)據(jù)庫(kù)(InstallDatabase.txt)、刪除數(shù)據(jù)庫(kù)(DropDatabase.txt)、初始化數(shù)據(jù)基本數(shù)據(jù)(InitializeData.txt)腳本文件,將屬性“生成操作”設(shè)為“嵌入的資源”。代碼如下: using System; using System.Collections; using System.ComponentModel; using System.Configuration.Install; using System.Data; using System.Data.SqlClient; using System.IO; using System.Reflection; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Text; using Microsoft.Win32; namespace install { /// /// Installer 的摘要說(shuō)明。 /// [RunInstaller(true)] public class Installer : System.Configuration.Install.Installer { /// /// 必需的設(shè)計(jì)器變量。 /// string conStr=”packet size=4096;integrated security=SSPI;”+ “data source=/”(local)/”;persist security info=False;”+ “initial catalog=master;connect timeout=300″; RijndaelCryptography rijndael = new RijndaelCryptography(); private System.ComponentModel.Container components = null; public Installer() { // 該調(diào)用是設(shè)計(jì)器所必需的。 InitializeComponent(); // TODO: 在 InitializeComponent 調(diào)用后添加任何初始化 } /// /// 清理所有正在使用的資源。 /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region 組件設(shè)計(jì)器生成的代碼 /// /// 設(shè)計(jì)器支持所需的方法 - 不要使用代碼編輯器修改 /// 此方法的內(nèi)容。 /// private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion #region 重載自定義安裝方法 protected override void OnBeforeInstall(IDictionary savedState) { base.OnBeforeInstall (savedState); } public override void Install(IDictionary stateSaver) { base.Install (stateSaver); string databaseServer = Context.Parameters[”server”].ToString(); string userName = Context.Parameters[”user”].ToString(); string userPass = Context.Parameters[”pwd”].ToString(); string targetdir = this.Context.Parameters[”targetdir”].ToString(); conStr = GetLogin(databaseServer,userName,userPass,”master”); SqlConnection sqlCon = new SqlConnection(); try { sqlCon.ConnectionString = conStr; sqlCon.Open(); rijndael.GenKey(); rijndael.Encrypt(conStr); stateSaver.Add(”key”,rijndael.Key); stateSaver.Add(”IV”,rijndael.IV); stateSaver.Add(”conStr”,rijndael.Encrypted); ExecuteSql(sqlCon,”InstallDatabase.txt”); ExecuteSql(sqlCon,”InitializeData.txt”); if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close(); } catch(SqlException) { MessageBox.Show(”安裝失敗!/n數(shù)據(jù)庫(kù)配置有誤,請(qǐng)正確配置信息!”,”錯(cuò)誤”,MessageBoxButtons.OK,MessageBoxIcon.Error); if(sqlCon.State!=ConnectionState.Closed) sqlCon.Close(); this.Rollback(stateSaver); } } protected override void OnAfterInstall(IDictionary savedState) { base.OnAfterInstall(savedState); } public override void Rollback(IDictionary savedState) { base.Rollback (savedState); } public override void Uninstall(IDictionary savedState) { base.Uninstall (savedState); if(savedState.Contains(”conStr”)) { string targetdir = this.Context.Parameters[”targetdir”].ToString(); RijndaelCryptography rijndael = new RijndaelCryptography(); rijndael.Key = (byte[])savedState[”key”]; rijndael.IV = (byte[])savedState[”IV”]; conStr = rijndael.Decrypt((byte[])savedState[”conStr”]); SqlConnection sqlCon = new SqlConnection(conStr); ExecuteDrop(sqlCon); } } #endregion #region 數(shù)據(jù)操作方法 //從資源文件獲取中數(shù)據(jù)執(zhí)行腳本 private static string GetScript(string name) { Assembly asm = Assembly.GetExecutingAssembly(); Stream str = asm.GetManifestResourceStream(asm.GetName().Name+ “.” + name); StreamReader reader = new StreamReader(str,System.Text.Encoding.Default); System.Text.StringBuilder output = new System.Text.StringBuilder(); string line = “”; while((line = reader.ReadLine())!=null) { output.Append(line + “/n”); } return output.ToString(); } //獲取數(shù)據(jù)庫(kù)登錄連接字符串 private static string GetLogin(string databaseServer,string userName,string userPass,string database) { return “server=” + databaseServer + “;database=”+database+”;User ID=” + userName + “;Password=” + userPass +”;connect timeout=300;”; } //執(zhí)行數(shù)據(jù)庫(kù)腳本方法 private static void ExecuteSql(SqlConnection sqlCon,string sqlfile) { string[] SqlLine; Regex regex = new Regex(”^GO”,RegexOptions.IgnoreCase | RegexOptions.Multiline); string txtSQL = GetScript(sqlfile); SqlLine = regex.Split(txtSQL); if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close(); sqlCon.Open(); SqlCommand cmd = sqlCon.CreateCommand(); cmd.Connection = sqlCon; foreach(string line in SqlLine) { if(line.Length>0) { cmd.CommandText = line; cmd.CommandType = CommandType.Text; try { cmd.ExecuteNonQuery(); } catch(SqlException ex) { //rollback string ss = ex.Message; ExecuteDrop(sqlCon); break; } } } } //刪除數(shù)據(jù)庫(kù) private static void ExecuteDrop(SqlConnection sqlCon) { if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close(); sqlCon.Open(); SqlCommand cmd = sqlCon.CreateCommand(); cmd.Connection = sqlCon; cmd.CommandText = GetScript(”DropDatabase.txt”); cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); sqlCon.Close(); } #endregion } 單擊“生成”菜單下“生成解決方案”,生成install.dll安裝類文件。 3、將“主程序”項(xiàng)目的輸出添加到部署項(xiàng)目中 在“文件系統(tǒng)編輯器”中,選擇“應(yīng)用程序文件夾”,單擊右鍵指向“添加”,添加“項(xiàng)目輸出”。 在“添加項(xiàng)目輸出組”對(duì)話框中,選擇“項(xiàng)目”下拉表框中選擇你的主安裝程序類,如上面的“install”。 從列表框中選擇“主輸出”組,然后單擊“確定”關(guān)閉。 4、創(chuàng)建自定義安裝對(duì)話框 在解決方案資源管理器中選擇安裝項(xiàng)目“Setup1”項(xiàng)目,在“視圖”菜單上指向“編輯器”,然后選擇“用戶界面”。 在用戶界面編輯器具中,選擇“安裝”下的“啟動(dòng)”節(jié)點(diǎn)。在“操作”菜單上,選擇“添加對(duì)話框”。 在“添加對(duì)話框”中選擇“文本框(A)”對(duì)話框,然后單擊“確定”關(guān)閉對(duì)話框。 在“操作”菜單上,選擇“上移”,重復(fù)此步驟,移到“安裝文件夾”上。 在“文本框(A)”上單擊“屬性窗口”,設(shè)置如下圖所示: 5、建自定義操作 在解決方案資源管理器中選擇安裝項(xiàng)目“Setup1”項(xiàng)目,在“視圖”菜單上指向“編輯器”,然后選擇“自定義操作”。 在“自定義操作編輯器”中選擇“安裝”節(jié)點(diǎn)。單擊右鍵“添加自定義操作”,在選擇項(xiàng)目中的項(xiàng)中選擇“應(yīng)用程序文件夾”,選擇“主輸出來(lái)自install(活動(dòng))”。 在“屬性窗口”中選擇“CustomActionData”屬性并鍵入“/server=[EDITA1] /user=[EDITA2] /pwd=[EDITA3] /targetdir=”[TARGETDIR]/””。 附:/targetdir=”[TARGETDIR]/”是安裝后的目標(biāo)路徑,為了在install類中獲得安裝后的路徑,我們?cè)O(shè)置此參數(shù)。 單擊“生成”菜單下的“生成解決方案”,編譯安裝項(xiàng)目。 .Net程序打包安裝與卸載制作——怎樣將MSDE Sp3打包進(jìn).Net安裝項(xiàng)目中?(四) 1、創(chuàng)建安裝項(xiàng)目“Setup1”安裝項(xiàng)目 在“文件”菜單上指向“添加項(xiàng)目”,然后選擇“新建項(xiàng)目”。 在“添加新項(xiàng)目”對(duì)話框中,選擇“項(xiàng)目類型”窗格中的“安裝和部署項(xiàng)目”,然后選擇“模板”窗格中的“安裝項(xiàng)目”。在“名稱”框中鍵入 “setup1”。 單擊“確定”關(guān)閉對(duì)話框。 項(xiàng)目被添加到解決方案資源管理器中,并且文件系統(tǒng)編輯器打開。 在“屬性”窗口中,選擇 ProductName 屬性,并鍵入”億萬(wàn)電器成套報(bào)價(jià)系統(tǒng)”。 2、下載MSDE Sp3 安裝程序與MSI安裝文件修改器(Orca)工具。 3、選擇“文件系統(tǒng)編輯器”,在“視圖“菜單上指向“添加”,然后選擇“合并模塊…”(Merge Moudle),在添加模塊中,找到MSDE sp3安裝文件所在目錄,將MSM和MSM/1033下的所有文件,添加進(jìn)來(lái)。 在安裝項(xiàng)目Setup1的屬性(Properties)中的“Search Path”,添加MSM和MSM/1033目錄。 單擊“生成菜單下的“生成解決方案”,編譯Setup1安裝項(xiàng)目工程。 用Orca MSI安裝文件修改器打開生成的安裝包(Setup1.msi)文件,在左列的表欄中 選擇“InstallExecuteSequence”表,修改下面的屬性值: GetSqlStates.XXXXXX 103改成421 RemoveExistingProducts值改成1800 InstallInitialize值改成1799 在InstallUISequence 選擇“InstallUISequence”表,修改下面的值: GetSqlStates.XXXXXX 103改成421 選擇“Property”表,添加以下三個(gè)屬性: SqlInstanceName:MSDEDH實(shí)例服務(wù)名 SqlSecurityMode:SQL(不加這行確實(shí)也行,就是沒(méi)辦法用SQL模式登錄) SqlSaPwd:sa的密碼 連接測(cè)試: 單擊修改過(guò)的Setup1.msi安裝文件,確認(rèn)是否能夠安裝; osql -S 機(jī)器名/MSDEDH實(shí)例服務(wù)名 -U sa -P sa密碼 能夠進(jìn)去——>OK!打包成功! .Net程序打包安裝與卸載制作 ——怎樣將MDAC打包進(jìn).Net安裝項(xiàng)目中?(五) 在“解決方案資源管理器”選擇Setup1安裝項(xiàng)目工程,選擇“視圖”菜單,指向“啟動(dòng)條件”,打開“啟動(dòng)條件”管理器。 在”啟動(dòng)條件”管理器中,右鍵點(diǎn)擊”目標(biāo)計(jì)算機(jī)上的要求”,在彈出的的菜單中選擇”添加注冊(cè)表啟動(dòng)條件”。你會(huì)發(fā)現(xiàn)在”搜索目標(biāo)計(jì)算機(jī)”中多了一項(xiàng)”搜索 RegistryEntry1″,在”啟動(dòng)條件”中多了一項(xiàng)”Condition1″。 選擇”搜索 RegistryEntry1″,在”屬性”對(duì)話框中填寫如下內(nèi)容: Property:MDACSEARCH RegKey:Software/Microsoft/DataAccess Root:vsdrrHKLM Value:FullInstallVer 選擇”Condition1″ ,在”屬性”對(duì)話框中填寫如下內(nèi)容: Condition:MDACSEARCH>=”2.6″ 進(jìn)行這一步是因?yàn)樵诎惭b.NET框架的時(shí)候需要MDAC。 .Net程序打包安裝與卸載制作 ——怎樣制作.Net卸載程序?(六) 方法一: 在打包項(xiàng)目中添加文件msiexec.exe(一般在c:/windows/system32(系統(tǒng)目錄中)找到)。 在文件系統(tǒng)視圖中選擇應(yīng)用程序文件,在msiexec.exe上單擊右鍵選擇“創(chuàng)建快捷方式”,重命名快捷方式為“uninst”. 更改此快捷方式Argmuments為“/x {產(chǎn)品ID}”,產(chǎn)品ID的值為打包項(xiàng)目的ProductCode屬性值。 方法二: 先生成安裝包,記下ProudctCode(選擇解決方案資源管理根目錄如Setup1,再查看屬性標(biāo)簽,不是右鍵屬性),下面用到 用Vs.Net 建立一個(gè)新的控制臺(tái)程序uninst.exe文件。 代碼如下: using System; namespace uninst { /// /// Class1 的摘要說(shuō)明。 /// class UnInstall { /// /// 應(yīng)用程序的主入口點(diǎn)。 /// [STAThread] static void Main(string[] args) { string sysroot = System.Environment.SystemDirectory; System.Diagnostics.Process.Start(sysroot + “//msiexec.exe”, “/x {850FED90-20D0-4EBA-BEDB-3D9DBA25F6EC} /qr”); } } } 編譯過(guò)后,將生成的uninst.exe文件添加到安裝包中,重新生成安裝項(xiàng)目。 .Net程序打包安裝與卸載制作 ——怎樣創(chuàng)建網(wǎng)頁(yè)快捷方式(“開始與程序”菜單中)?(七) 將要添加的網(wǎng)頁(yè)快捷方式選中,按住鼠標(biāo)不放,將其拖入你的.net安裝程序中的用戶的“程序”菜單或用戶的“開始”菜單即可,這樣你的網(wǎng)頁(yè)快捷方式就可以像創(chuàng)建其它文件一樣的被創(chuàng)建在windows的開始菜單與程序菜單中了!
|
|
來(lái)自: 履歷館 > 《visual studio 2008》