1、創建安裝項目“Setup1”安裝項目
在“文件”菜單上指向“添加項目”,然後選擇“新建項目”。
在“添加新項目”對話框中,選擇“項目類型”窗格中的“安裝和部署項目”,然後選擇“模板”窗格中的“安裝項目”。在“名稱”框中鍵入 “setup1”。
單擊“確定”關閉對話框。
項目被添加到解決方案資源管理器中,並且文件系統編輯器打開。
在“屬性”窗口中,選擇 ProductName 屬性,並鍵入”億萬電器成套報價系統”。
2、在安裝項目中創建安裝程序類(install.cs)。
添加創建數據庫(InstallDatabase.txt)、刪除數據庫(DropDatabase.txt)、初始化數據基本數據(InitializeData.txt)腳本文件,將屬性“生成操作”設爲“嵌入的資源”。代碼如下:
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
{
/// <summary>
/// Installer 的摘要說明。
/// </summary>
[RunInstaller(true)]
public class Installer : System.Configuration.Install.Installer
{
/// <summary>
/// 必需的設計器變量。
/// </summary>
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()
{
// 該調用是設計器所必需的。
InitializeComponent();
// TODO: 在 InitializeComponent 調用後添加任何初始化
}
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region 組件設計器生成的代碼
/// <summary>
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
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數據庫配置有誤,請正確配置信息!","錯誤",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 數據操作方法
//從資源文件獲取中數據執行腳本
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();
}
//獲取數據庫登錄連接字符串
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;";
}
//執行數據庫腳本方法
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;
}
}
}
}
//刪除數據庫
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、將“主程序”項目的輸出添加到部署項目中
在“文件系統編輯器”中,選擇“應用程序文件夾”,單擊右鍵指向“添加”,添加“項目輸出”。
在“添加項目輸出組”對話框中,選擇“項目”下拉表框中選擇你的主安裝程序類,如上面的“install”。
從列表框中選擇“主輸出”組,然後單擊“確定”關閉。
4、創建自定義安裝對話框
在解決方案資源管理器中選擇安裝項目“Setup1”項目,在“視圖”菜單上指向“編輯器”,然後選擇“用戶界面”。
在用戶界面編輯器具中,選擇“安裝”下的“啓動”節點。在“操作”菜單上,選擇“添加對話框”。
在“添加對話框”中選擇“文本框(A)”對話框,然後單擊“確定”關閉對話框。
在“操作”菜單上,選擇“上移”,重複此步驟,移到“安裝文件夾”上。
在“文本框(A)”上單擊“屬性窗口”,設置如下圖所示:
5、建自定義操作
在解決方案資源管理器中選擇安裝項目“Setup1”項目,在“視圖”菜單上指向“編輯器”,然後選擇“自定義操作”。
在“自定義操作編輯器”中選擇“安裝”節點。單擊右鍵“添加自定義操作”,在選擇項目中的項中選擇“應用程序文件夾”,選擇“主輸出來自install(活動)”。
在“屬性窗口”中選擇“CustomActionData”屬性並鍵入“/server=[EDITA1] /user=[EDITA2] /pwd=[EDITA3] /targetdir="[TARGETDIR]/"”。
附:/targetdir="[TARGETDIR]/"是安裝後的目標路徑,爲了在install類中獲得安裝後的路徑,我們設置此參數。
單擊“生成”菜單下的“生成解決方案”,編譯安裝項目。
添加一個class到打包程序中,可以解決很多打包程序無法解決的問題
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/cnming/archive/2009/06/29/4305774.aspx