在打包程序中自动安装SQL Server数据库

来源:互联网 发布:mac os 修复 编辑:程序博客网 时间:2024/05/16 11:39

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)”对话框,然后单击“确定”关闭对话框。

在“操作”菜单上,选择“上移”,重复此步骤,移到“安装文件夹”上。

在“属性”窗口中,选择 BannerText 属性并键入:安装数据库.

 选择 BodyText 属性并键入:安装程序将在目标机器上安装数据库
 选择 Edit1Label 属性并键入:数据库名称:
 选择 Edit1Property 属性并键入 CUSTOMTEXTA1
 选择 Edit1Value 属性并键入:dbservers
 选择 Edit2Label 属性并键入:服务器名:
 选择 Edit2Property 属性并键入 CUSTOMTEXTA2
 选择 Edit2Value 属性并键入:(local)
 选择 Edit3Label 属性并键入:用户名:
 选择 Edit3Value 属性并键入:sa
 选择 Edit3Property 属性并键入 CUSTOMTEXTA3
 选择 Edit4Label 属性并键入:密码:
 选择 Edit4Property 属性并键入 CUSTOMTEXTA4
 选择 Edit2Visible、Edit3Visible 和 Edit4Visible 属性,并将它们设置为 true

    

5、建自定义操作

在解决方案资源管理器中选择安装项目“Setup1”项目,在“视图”菜单上指向“编辑器”,然后选择“自定义操作”。

在“自定义操作编辑器”中选择“安装”节点。单击右键“添加自定义操作”,在选择项目中的项中选择“应用程序文件夹”,选择“主输出来自install(活动)”。

在“属性窗口”中选择“CustomActionData”属性并键入“/server=[EDITA1] /user=[EDITA2] /pwd=[EDITA3]  /targetdir="[TARGETDIR]/"”。

附:/targetdir="[TARGETDIR]/"是安装后的目标路径,为了在install类中获得安装后的路径,我们设置此参数。

单击“生成”菜单下的“生成解决方案”,编译安装项目。

添加一个class到打包程序中,可以解决很多打包程序无法解决的问题

六).添加文件
1. 将SQL Server备份成文件DB.dat添加到“setup1”项目(在企业管理器中右击数据库->所有工作->备份数据库,备份成一个文件,取名为DB.dat)
2. 将安装文件LisenceFile.rtf添加到“setup1”项目
3. 在用户界面编辑器中,选择许可协议,设置LisenceFile属性为LisenceFile.rtf文件
4.一般会自动将依赖项添加到“检测到的依赖项”,如果没有,那么我们要手动将其加入步骤5)
         Crystal_Managed2003.msm     (如果有水晶报表)
         dotnetfxredist_x86.msm      (.net一定是必须的)
          ...                         (如果有引用其他的dll)
5.如果使用了水晶报表,手动加入要包含的文件:项目-->添加-->合并模块(添加你的程序文件) (包括dotNetFramework和MDAC27),位于:C:/Program Files/Common Files/Merge Modules/ 下,*为必要的
具体功能如下:
       (托管组件 MSM 处理所有托管组件的分发,其中包括 Windows 窗体查看器、Web 窗体查看器和所有 Crystal Decisions 命名空间)
       * Crystal_Managed2003.msm
          Crystal_Managed2003_chs.msm
       (对于使报表运行所需的所有其他文件,由数据库访问 MSM 处理其分发。其中包括数据库、导出和图表驱动程序。)
        * Crystal_Database_access2003.msm
           Crystal_Database_access2003_chs.msm
        (KeyCode MSM 处理 Crystal Decisions 密钥号码的安装,注意是添加合并模块,否则没有“MergeMouduleProperties”属性)
        * Crystal_regwiz2003.msm
        (如果报表文件使用了 ADO.NET 的 dataset 数据集对象,那么 VC_User_CRT71_RTL_X86_---.msm 和 VC_User_STL71_RTL_X86_---.msm 模块也必须包含在安装工程中。而且这两个模块的文件安装属性的"Module Retargetable Folder"项必须修改成为系统目录)
           VC_User_CRT71_RTL_X86_---.msm
           VC_User_STL71_RTL_X86_---.msm
        (很多人经常出现查询错误,不妨加上这个)
5.打开解决方案-->右键点击Crystal_regwiz2003.msm的属性,在“MergeMouduleProperties”里的“License Key”填入:AAP5GKS0000GDE100DS(这个是你生成Crystal Report是用到的注册号的密码!)

 七).打包時加入卸载功能:
方法一:
1.在打包項目中添加文件msiexec.exe(一般可在c:/windows/system32/下找到)
2.在文件系統視圖中選擇應用程序文件夾,在msiexec.exe上按右鍵,選擇創建快捷方式,重命名快捷方式為"卸载".
3.更改此快捷方式的Arguments 为"/x {產品id}",產品id的值為打包項目的ProductCode屬性值.
方法二:(推荐)
1.先生成安装包,记下ProductCode(选择解决方案资源管理器根目录如setup1,再查看属性标签,不是右键中的属性),下面要用到
2.用VS.net建立一个新的控制台程序uninst.exe文件
'power by: landlordh
'for 2000,xp,2003
Module uninstall
    Sub Main()
        Dim myProcess As Process = New Process
        If System.Environment.OSVersion.ToString.IndexOf("NT 5") Then
            myProcess.Start("msiexec", "/X{2B65D4A9-C146-4808-AB4B-321FB0779559}")  '改为自己的ProductCode
        End If
        myProcess.Close()
    End Sub
End Module
3.将控制台程序BIN目录的exe文件加入到打包程序文件中,在程序组创建uninst.exe的快捷方式
原创粉丝点击