c# winform 打包(帶數據庫安裝)

http://www.cnblogs.com/scottckt/archive/2011/05/14/2046313.html

 

使用VS 自帶的打包工具,製作winform安裝項目

    開發環境:VS 2008 Access

    操作系統:Windows XP

    開發語言:C#

    項目名稱:**管理系統

 

步驟:

    第一步:打開開發環境VS2008,新建項目,選擇其他項目類型,再選擇"安裝項目",輸入名稱及選擇安裝路徑;

 

 

 

    第二步:進入文件系統選項卡,選擇應用程序文件夾,在中間的空白區域右鍵選擇"添加文件",添加項目文件(exe,dll);

 

 

   注:如果安裝項目在你的項目中。建議使用項目輸出的形式。這樣項目變更時,安裝程序也會相應的變更。如下圖。主輸出一定要選擇你要打包的項目。

 

 

 

 

 

    第三步:添加項目所需文件;這裏有兩個文件夾需要注意(DataBase和Report),因爲DataBase是存儲項目數據庫,而Report則是存儲項目所需的報表文件.rpt,因此呢,在應用程序夾中也需要建同名的文件夾,並且添加所需的文件。效果:

 

 

 

    第四步:爲了在開始程序菜單中和桌面應用程序中看到安裝程序,這裏我們就需要爲項目創建快捷方式。右鍵選擇可執行文件 (PersonFinance.exe),創建快捷方式,進行重命名"**公司**管理系統",將該快捷方式拖放到 '用戶的"程序"菜單' 中。重複該步驟將新建的快捷方式添加到 "用戶桌面" 文件夾中

    最好在用戶菜單中建立一個文件夾,存放安裝程序

 

 

 

    第五步:設置系統必備,右鍵選擇安裝項目,進入屬性頁中,單擊"系統必備"按鈕,進入系統必備對話框;勾選"創建用於安裝系統必備組件的安裝程序",在安裝系統必備組件列表中,選擇

            1)、Windows Installer 3.1(必選)

            2)、.NET Framework 3.5 (可選)參考最後說明

            3)、Crystal Report Basic for Visual Studio2008(x86,x64) (可選) 項目中用到了水晶報表就需要勾選此項

重要一點:勾選"從與我的應用程序相同的位置下載系統必備組件(D)",其實意思就是說你勾選後,生成安裝項目時,在你安裝項目的路徑下,會有你在系統必備組件列表中勾選的組件.(系統自動完成,這一點還不錯,不需要你自己去下載組件)

 

 

 

    第六步:卸載程序,因爲安裝包做好之後不能只有安裝程序,還要有卸載程序

           首先呢,在"C:/WINDOWS/system32"路徑下,找到msiexec.exe 添加到應用程序文件夾中,創建快捷方式,並命名"卸載管理系統"或"Uninstall"

           其次呢,選擇安裝項目的ProductCode

           

 

            右鍵選擇卸載程序的快捷方式,進入屬性,在Arguments選項中 輸入/x 及ProductCode; 例如:/x {6931BD71-5C5E-4DA1-A861-14C7D1A78B97}

            將卸載程序同時存放到用戶的開始菜單的文件夾中(在第四步中新建)

第七步:更改安裝程序屬性,右鍵選擇安裝項目屬性,可以設置項目作者及名稱,其他屬性信息可以根據實際情況進行設置.

 

 

 

第八步:生成安裝項目

           生成時,會出現些警告:應將“msiexec.exe”排除,原因是其源文件“C:/WINDOWS/system32/msiexec.exe”受到“Windows 系統文件保護”。 

                                          兩個或多個對象具有相同的目標位置(“[targetdir]/model.dll”)
           解決方案:

           第一種:都不處理

           第二種:第一類警告,可以編寫卸載程序

                      第二種警告:刪除相同的文件

 

安裝項目製作完畢.

 

 

 

安裝及運行

    直接運行steup.msi 或是setup.exe 會出現

 

 

 

    在桌面和開始菜單中也會有相應的安裝程序、卸載程序。

 

 

說明及小結:

    1、.net framework 框架是可選的,不一定說你採用的是VS2008開發就必須要使用.net framework 3.5,只要你在程序中沒有使用到.net framework 3.5 的特性比如(LINQ),那麼你選擇框架時,是可以選擇2.0的,爲什麼?因爲2.0只有20多MB,而3.5則有200多MB。

更改方式:在安裝項目下面有個檢測到的依賴項文件,雙擊裏面的Microsoft .net framework,進入了啓動條件選擇卡,右鍵選擇.net frmaework 在Version中選擇你所需的.net framework框架

 

 

 

 

 

 

 

 

 

----------------------------------------------------------------------------------------------------

 

安裝已會做,看看如何打包數據庫。網上已有人寫了文章,(C# WINFORM 打包數據庫):http://www.cnblogs.com/pato/archive/2010/09/16/1828276.html

C# WINFORM 打包數據庫

 

實現效果:安裝項目時直接附加數據庫。

1.首先在需要部署的項目的解決方案資源管理器中新建一個安裝項目

 
 
2.在安裝項目的文件視圖中,右鍵【應用程序文件夾】->【添加】->【項目輸出】

 

 

 

 

    選擇你的項目中的啓動項目,下面的列表中,默認就是主輸出,確定。
3.此時在文件系統的中間欄目,會自動列出編譯所需的文件。一個簡單項目打包差不多,還有快捷方式什麼的,就不說了。開始重點了。

創建安裝程序類
4.在解決方案資源管理器中,新建一個類庫項目【InstallDB】,刪除Class1.cs,新建一個安裝程序類[InstallDB.cs],等下將在這個類中編寫附加數據庫代碼。

 

 

創建自定義安裝對話框
5.在剛新建的安裝項目上右鍵,【視圖】->【用戶界面】:

 

 

 

 

 

在用戶界面中,右鍵【啓動】-【添加對話框】-選擇【文本框(A)】-確定。
6.然後右鍵這個文本框(A),將其上移到歡迎使用下面:

 

 

右鍵選擇【屬性】,參考下圖的信息填寫:

 

 

 

 

 

 

7.在剛新建的安裝項目上右鍵,【視圖】->【自定義操作】:
8.右鍵【自定義操作界面】的【安裝】節點,【添加自定義操作】,彈出的對話框。
9.在查找範圍裏選擇應用程序文件夾,再點擊右側的【添加輸出(O)…】,選擇剛新建的安裝程序類項目,默認還是主輸出,確定。此時:

 

 

 

 

10.右鍵這個【主輸出來自InstallDB(活動)】,進入屬性界面,在【CustomActionData】屬性裏輸入下面的內容:
/dbname=[DBNAME] /server=[SERVER] /user=[USER] /pwd=[PWD] /targetdir="[TARGETDIR]/"

  說明:其中前四個方括號中的大寫字母,爲上面第6步圖中輸入的四個EditProPerty屬性,需要對應好。最後一個targetdir的值的意思是安裝後文件的目錄路徑。
  特別提醒:前三個"/XXX=[XXX]"後面  ,都有一個空格的,小xin曾因此煩惱甚久,網上的某些教程實在是。。。很耐人。
11.現在可以添加數據庫文件了,在剛新建的安裝項目上右鍵,【添加】->【文件】,選擇你的MDF和LDF文件,就是安裝時需要附加的數據庫文件。
12.最後,我們只需在安裝程序類裏編寫附加數據庫的代碼了。打開上面第4步中新建的安裝程序類,參考下方的代碼,編寫適合您的附加數據庫代碼:
 
/// <summary>
/// 附加數據庫方法
/// </summary>
/// <param name="strSql">連接數據庫字符串,連接master系統數據庫</param>
/// <param name="DataName">數據庫名字</param>
/// <param name="strMdf">數據庫文件MDF的路徑</param>
/// <param name="strLdf">數據庫文件LDF的路徑</param>
/// <param name="path">安裝目錄</param>
private   void  CreateDataBase( string  strSql, string  DataName,  string  strMdf,  string  strLdf, string  path)
{
   SqlConnection myConn 
= new SqlConnection(strSql);
   String str 
= null ;
   
try
   {
      str 
= " EXEC sp_attach_db @dbname='"+DataName+"',@filename1='"+strMdf+"',@filename2='"+strLdf+"'";
      SqlCommand myCommand 
= new SqlCommand(str, myConn);
      myConn.Open();
      myCommand.ExecuteNonQuery();
      MessageBox.Show(
"數據庫安裝成功!點擊確定繼續");//需Using System.Windows.Forms
   }
   
catch(Exception e)
   {
      MessageBox.Show(
"數據庫安裝失敗!" + e.Message+"/n/n"+"您可以手動附加數據");
      System.Diagnostics.Process.Start(path);
//打開安裝目錄
   }
   
finally
   {
      myConn.Close();
   }
}
public override void Install(System.Collections.IDictionary stateSaver)
{
   
string server = this.Context.Parameters["server"];//服務器名稱
    string uid = this.Context.Parameters["user"];//SQlServer用戶名
    string pwd = this.Context.Parameters["pwd"];//密碼
    string path = this.Context.Parameters["targetdir"];//安裝目錄
    string strSql = "server=" + server + ";uid=" + uid + ";pwd=" + pwd + ";database=master";//連接數據庫字符串
    string DataName = "JXC";//數據庫名
    string strMdf = path + @"JXC.mdf";//MDF文件路徑,這裏需注意文件名要與剛添加的數據庫文件名一樣!
    string strLdf = path + @"jxc_log.ldf";//LDF文件路徑
    base.Install(stateSaver);
   
this.CreateDataBase(strSql, DataName, strMdf, strLdf, path);//開始創建數據庫
}

 

 --------------------------------------------------------------------------------

 

自已實現數據庫配置

 

    上邊程序中是通過【添加自定義操作】實現數據庫輸入的。如果我們想在安裝時可以讓用戶有測試數據庫連接功能、並且是通過SQL語句創建數據庫,那怎麼做呢?

 我們可以在上邊的自定義操作的類庫中添加一個From界面。通過它來完成。如下界面。當然,上邊文章中自定義界面的數據庫部分就可以不要了。

 

 

 

 在上邊文章的自定義類庫中編寫代碼。

此代碼的主要功能是:

     1)創建數據庫

     2)創建數據庫表、存儲過程等內容

     3)修改安裝程序配置文件.

 

#region 參數
        
public static string _serverName { getset; }
        
public static string _dbName { getset; }
        
public static string _userName { getset; }
        
public static string _password { getset; }
        
private string _setupType { getset; }
        
private string _targetDir { getset; }

        
/// <summary>
        
/// 資源中創建表結構及數據的文件名
        
/// </summary>
        private const string _StructureAndDataFileName = "CreateStructureData";
        
#endregion


        
public override void Install(IDictionary stateSaver)
        {

            
base.Install(stateSaver);

            
//數據庫配置 界面
            frmDb dbFrom = new frmDb();
            DialogResult DialogResult 
= dbFrom.ShowDialog();
            
if (DialogResult != DialogResult.OK)
            {
                
throw new InstallException("用戶取消安裝!");
            }
            SqlConnection connection 
= null;
                connection 
= TestConnection(_serverName, "master", _userName, _password);
                
//創建數據庫
                int result = this.CreateDataBase(connection);
                
if (result > 0)
                {
                    CloseConnection(connection);
                    
//使用創建的數據庫
                    connection = TestConnection(_serverName, _dbName, _userName, _password);
                    CreateStructureAndData(connection);
                }
                
//創建表及增加數據
                CreateStructureAndData(connection);
            
//爲空是表示有錯誤
            if (connection != null)
            {
                ModifyConfig();
            }
            
//關閉數據庫
            CloseConnection(connection);
        }


        
/// <summary>
        
/// 關閉數據庫
        
/// </summary>
        
/// <param name="connection"></param>
        private void CloseConnection(SqlConnection connection)
        {
            
if (connection != null)
            {
                
//關閉數據庫
                if (connection.State != System.Data.ConnectionState.Closed)
                {
                    connection.Close();
                    connection.Dispose();
                }
            }
        }

        
/// <summary>
        
/// 測試連接
        
/// </summary>
        
/// <param name="serverName"></param>
        
/// <param name="dbName"></param>
        
/// <param name="userName"></param>
        
/// <param name="password"></param>
        private SqlConnection TestConnection(string serverName, string dbName, string userName, string password)
        {
            
string connectionString = GetConnectionString(serverName, dbName, userName, password);
            SqlConnection connection 
= new SqlConnection(connectionString);
            
try
            {
                
if (connection.State != ConnectionState.Open)
                {
                    connection.Open();
                }
                
return connection;
            }
            
catch
            {
                CloseConnection(connection);
                
throw new InstallException("安裝失敗!/n數據庫配置有誤,請正確配置信息!");
            }
        }


        
/// <summary>
        
/// 得到連接字符串
        
/// </summary>
        
/// <param name="serverName"></param>
        
/// <param name="dbName"></param>
        
/// <param name="userName"></param>
        
/// <param name="password"></param>
        
/// <returns></returns>
        private string GetConnectionString(string serverName, string dbName, string userName, string password)
        {

            string connectionString = "Data Source={0};Initial Catalog={1};User ID={2};Password={3}";
            connectionString 
= string.Format(connectionString, serverName, dbName, userName, password);
            
return connectionString;
        }

        
/// <summary>
        
/// 創建數據庫
        
/// </summary>
        
/// <param name="serverName"></param>
        
/// <param name="dbName"></param>
        
/// <param name="userName"></param>
        
/// <param name="password"></param>
        
/// <param name="connection"></param>
        
/// <param name="stateSaver"></param>
        public int CreateDataBase(SqlConnection connection)
        {
            
int result = -1;
            connection.ChangeDatabase("master");
            
string createDBSql = @" if Exists(select 1 from sysdatabases where [name]=N'{0}')
                                    begin
                                    drop database {0}
                                    end
                                    GO 
                                    CREATE DATABASE {0} 
";
            createDBSql 
= string.Format(createDBSql, _dbName);
            //因爲有Go在SQLCommand中不認識,所以以Go爲分隔符取sql語句
            char[] split = new char[] { 'G''O' };
            
string[] sqlList = createDBSql.Split(split);

            SqlCommand command 
= null;
            
try
            {
                command 
= connection.CreateCommand();
                command.CommandType 
= System.Data.CommandType.Text;
                
foreach (string sqlItem in sqlList)
                {
                    
if (sqlItem.Length > 2)
                    {
                        command.CommandText 
= sqlItem;
                        result 
= command.ExecuteNonQuery();
                    }
                }
                
return result;
            }
            
catch
            {
                CloseConnection(connection);
                command.Dispose();
                
throw new InstallException("安裝失敗!/n數據庫配置不正確!");
            }
        }

        
/// <summary>
        
/// 分隔SQL語句
        
/// </summary>
        
/// <param name="sql"></param>
        
/// <returns></returns>
        private string[] splitSql(string sql)
        {
            Regex regex 
= new Regex("^GO", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            
string[] sqlList = regex.Split(sql.ToUpper());
            
return sqlList;
        }

        
/// <summary>
        
/// 創建表結構及數據
        
/// </summary>
        
/// <param name="connection"></param>
        public void CreateStructureAndData(SqlConnection connection)
        {
            StringBuilder builder 
= new StringBuilder();
            SqlCommand command 
= null;
            
//錯誤標誌
            bool isHaveError = false;
            
try
            {
                ResourceManager manager 
= new ResourceManager(typeof(YXSchoolSetupService.Properties.Resources));
                
if (manager != null)
                {
                    connection.ChangeDatabase(_dbName);
                    command 
= connection.CreateCommand();
                    command.CommandType 
= CommandType.Text;
                    builder.Append(manager.GetString(_StructureAndDataFileName));
                    
string[] sqlList = splitSql(builder.ToString());
                    
foreach (string sqlItem in sqlList)
                    {
                        
if (sqlItem.Length > 2)
                        {
                            command.CommandText 
= sqlItem;
                            command.ExecuteNonQuery();
                        }
                    }
                }
                
else
                {
                    isHaveError 
= true;
                }
                
if (true == isHaveError)
                {
                    CloseConnection(connection);
                    command.Dispose();
                    
throw new InstallException("數據庫配置失敗!/n請與開發人員聯繫!");
                }
            }
            
catch
            {
                CloseConnection(connection);
                command.Dispose();
                
throw new InstallException("數據庫配置失敗!/n請與開發人員聯繫!");
            }
        }

        
#region 修改web.config的連接數據庫的字符串

        
public void ModifyConfig()
        {

            System.IO.FileInfo FileInfo = new System.IO.FileInfo(_targetDir + "YXData.yixian");
            
if (!FileInfo.Exists) //不存在web.config文件
            {
                throw new InstallException("沒有找到文統配置文件!");
            }
            System.Xml.XmlDocument xmlDocument 
= new System.Xml.XmlDocument();
            xmlDocument.Load(FileInfo.FullName);
            
try
            {
                XmlElement element 
= xmlDocument.DocumentElement;
                
if (element != null)
                {
                    
foreach (XmlNode node in element)
                    {
                        
switch (node.Name)
                        {
                            
case "dbserver":
                                node.InnerText 
= _serverName;
                                
break;
                            
case "dbname":
                                node.InnerText 
= _dbName;
                                
break;
                            
case "dbpassword":
                                node.InnerText 
= _password;
                                
break;
                            
case "dbuser":
                                node.InnerText 
= _userName;
                                
break;
                            
default:
                                
break;
                        }
                    }
                }
                xmlDocument.Save(FileInfo.FullName);
            }
            
catch
            {
                
throw new InstallException("修改web.config配置文件失敗!");
            }
        }
        
#endregion

 

 

數據據庫測試界面中的代碼:

 

        /// <summary>
        
/// 連接測試是否成功
        
/// </summary>
        public bool isConnect { getset; }

        
private void frmDb_Load(object sender, EventArgs e)
        {           
            btnNext.Enabled 
= false;
            
this.CenterToParent();
        }
        
private void btnTest_Click(object sender, EventArgs e)
        {  
//將得到配置值傳給主安裝程序類
            
string serverName = txbServer.Text.Trim();
            DBInstaller._serverName 
= serverName;
            
string dbName = txbDbName.Text.Trim();
            DBInstaller._dbName 
= dbName;
            
string userName = txbUserName.Text.Trim();
            DBInstaller._userName 
= userName;
            
string password = txbPwd.Text.Trim();
            DBInstaller._password 
= password;
            isConnect 
= InstallCommon.TestConnection(serverName, dbName, userName, password);//測試連接,此處調用其它類中的代碼。
            
if (isConnect == true)
            {
                lblInfo.Text 
= "數據庫連接測試成功!";
                btnNext.Enabled 
= true;
            }
            
else
            {
                btnNext.Enabled 
= false;
                lblInfo.Text 
= "數據庫連接測試失敗!";
            }
        }
       
//取消按鈕
        
private void btnCancel_Click(object sender, EventArgs e)
        {
            
this.DialogResult = DialogResult.No;
            
this.Close();
        }
       
//下一步按鈕
        
private void btnNext_Click(object sender, EventArgs e)
        {
            
if (isConnect)
            {
                
this.DialogResult = DialogResult.OK;
            }
            
this.Close();
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章