zoukankan      html  css  js  c++  java
  • [转]asp.net 部署数据库、开始菜单、桌面快捷方式实例

    本文转自:http://adandelion.cnblogs.com/archive/2006/02/12/329130.html
    原文如下:
    ---------

    简单的ASP.NET部署,运行环境:vs2003,SqlServer2000

    (一)前提:
    http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=627921a0-d9e7-43d6-a293-72f9c370bd19
    下载"Microsoft Visual Studio .NET 2003 引导程序插件",它用于在 Microsoft® Visual Studio® .NET 2003 中创建包含 .NET Framework 1.1 版和/或 Microsoft Data Access Components (MDAC) 2.7 版的部署项目。

    (二)建立简单的asp.net项目WebSetupTest

    1.web.config文件里添加保存数据库连接字符串的key,部署的时候将初始化它.

    <appSettings>
      
    <add key="Conn_WebSetupTest" value=""></add>

    </appSettings>

    2.
    创建index.aspx文件

    <form id="Form1" method="post" runat="server">
       测试部署数据库和开始菜单/桌面快捷方式
       
    <br>

       
    <asp:DataGrid id="DataGrid1" runat="server" Width="100%" AllowPaging="True" PageSize="5">

        
    <PagerStyle Mode="NumericPages"></PagerStyle>

       
    </asp:DataGrid><br>

       
    <align="center"><img src="images/images_res.gif"></p>

    </form>

    index.aspx.cs里绑定数据   

    private void InitData()
            
    {
                connE.strSql 
    = "select * from users order by id desc"
    ;
                DataGrid1.DataSource 
    =
     connE.GetDt();
                DataGrid1.DataBind();
            }

    3.项目根目录下创建SqlScript目录用来存放部署数据需要的3个数据库脚本文件
     (1)CreateDataBase.sql用来创建数据库 --创建数据库<<DATABASE_NAME>>

    Use Master
    Go

    IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = '<<DATABASE_NAME>>'
    )
     
    DROP DATABASE [<<DATABASE_NAME>>]

    GO

     
    Create Database <<DATABASE_NAME>>

    Go


    use <<DATABASE_NAME>>

    --创建表

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Users]'and OBJECTPROPERTY(id, N'IsUserTable'= 1
    )
    drop table [dbo].[Users]

    GO


    CREATE TABLE [dbo].[Users]
     (
     
    [id] [int] IDENTITY (11NOT NULL
     ,
     
    [name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL
     ,
     
    [address] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL
     ,
     
    [createDate] [datetime] NULL
     
    ON [PRIMARY]

    GO

     (2)InsertData.sql用来向数据库里插入记录

    --增加记录
    declare @i int

    set @i= 0


    set xact_abort on

    begin transaction


    while @i<50

    begin

     
    insert into users (name,address,createdate) values ('name'+cast(@i as varchar),'address'+cast(@i as varchar),getDate
    ())
     
    set @i = @i+1

    end


    --rollback transaction

    commit transaction

    set xact_abort off

    (3)DropDataBase.sql用来卸载的时候删除数据库.

    --删除数据库
    IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = '<<DATABASE_NAME>>'
    )
     
    DROP DATABASE [<<DATABASE_NAME>>]

    4.把快捷方式图标文件usa_folder_dialup.ico放在项目根目录下的确images目录里.

    (三)在同一解决方案里添加"类库"项目WebSetupLib

    1.把存放数据库脚本文件名称的DataBase.xml和用户许可协议文件UserProtocol.rtf放在Resources目录下.
    UserProtocol.rtf文件可以通过Word直接创建,DataBase.xml要作为嵌入式资源,设置方法如图:


    DataBase.xml内容:

    <?xml version="1.0" encoding="utf-8" ?> 
    <configroot>

     
    <Files>

      
    <DataBase>

       
    <Add>

        
    <File name="CreateDataBase.sql"/>

       
    </Add>

       
    <Remove>

        
    <File name="DropDataBase.sql"/>

       
    </Remove>

      
    </DataBase>

      
    <Insert>

       
    <File name="InsertData.sql"/>

      
    </Insert>

      
     
    </Files>
     
    </configroot>

    2.添加部署数据库的类文件DataBase.cs,在下面的安装程序类文件WebSetupTest.cs里将使用此类
    sing System;
    using System.Diagnostics;
    using System.Configuration.Install;
    using System.Xml ;
    using System.Windows.Forms;

    namespace WebSetupLib
    {
     /**//// <summary>
     /// DataBase 的摘要说明。
     /// </summary>
     public class DataBase
     {
      string serverName=null;
      string databaseName =null;
      string userName=null;
      string Password=null;
      bool trustedconnection=false;
      string targetPath=null;
      XmlDocument config=null;
      public const string CONST_DATBASE_PLACEHOLDER ="<<DATABASE_NAME>>";
     
      //构造方法#region //构造方法
      public DataBase()
      {
       //
       // TODO: 在此处添加构造函数逻辑
       //
       //System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("WebSetupLib.DataBase.xml");
       System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("WebSetupLib.Resources.DataBase.xml");
       config=new XmlDocument();
       //MessageBox.Show("before load1111");
       config.Load(stream);
       //MessageBox.Show("after load 111");
      }

      public DataBase(string servername,string databasename,string username,
       string password,string targetpath):this()
      {
       this.serverName =servername;
       this.databaseName=databasename;
       this.userName=username;
       this.Password=password;
       this.targetPath=targetpath;
      }
      /**//// <summary>
      /// 信任连接
      /// </summary>
      /// <param name="servername"></param>
      /// <param name="databasename"></param>
      /// <param name="targetpath"></param>
      public DataBase(string servername,string databasename,string targetpath):this()
      {
       this.serverName =servername;
       this.databaseName=databasename;
       this.trustedconnection=true;
       this.targetPath =targetpath;
      }

      #endregion

      /**//// <summary>
      /// 安装数据库
      /// </summary>
      /// <returns></returns>
      public  bool  CreateDataBase()
      {
       string fileName=null;
       try
       {
        ProcessStartInfo processInfo =new ProcessStartInfo("osql.exe");
        processInfo.WindowStyle=ProcessWindowStyle.Hidden;

        //Get the name of the file from the assembly's embedded resource.
        //MessageBox.Show("createDatabase");
        if(config !=null)
        {
         fileName = config.SelectSingleNode("configroot/Files/DataBase/Add/File").Attributes["name"].Value;
        }
        else
        {
         throw new InstallException("创建数据库的脚本文件不存在!");
        }

        //Get arguments
        //MessageBox.Show("master");
        processInfo.Arguments=GetCommonProcessArguments(fileName,"master");
        
        EventLog.WriteEntry("安装数据库",processInfo.Arguments);
        PopulateDatabaseNamePlaceHolder(GetFullPath(fileName));
        Process osql = Process.Start(processInfo);
        //Wait till it is done
        osql.WaitForExit();
        EventLog.WriteEntry( "安装数据库","数据库创建完成..");
        osql.Dispose();
        return true;
       }
       catch(Exception ex)
       {
        //Customize if required.
        EventLog.WriteEntry("安装数据库",ex.Message,EventLogEntryType.Error) ;
        throw new InstallException(ex.Message);
       }
      }
     
      /**//// <summary>
      /// 删除数据库
      /// </summary>
      /// <returns></returns>
      public bool DropDataBase()
      {
       string fileName=null;
       try
       {
        ProcessStartInfo processInfo =new ProcessStartInfo("osql.exe");
        processInfo.WindowStyle=ProcessWindowStyle.Hidden;
       
        //Get the name of the file from the assembly's embedded resource.
        if(config !=null)
        {
         fileName = config.SelectSingleNode("configroot/Files/DataBase/Remove/File").Attributes["name"].Value;
        }
        else
        {
         throw new InstallException("删除数据库的脚本文件不存在!");
        }
         
        //Get arguments
        processInfo.Arguments=GetCommonProcessArguments(fileName,"master");

        EventLog.WriteEntry("安装数据库",processInfo.Arguments);
        PopulateDatabaseNamePlaceHolder(GetFullPath(fileName));
        Process osql = Process.Start(processInfo);
        osql.WaitForExit();
        EventLog.WriteEntry("安装数据库","删除数据库");
        osql.Dispose();
        return true;
       }
       catch(Exception ex)
       {
        //Customize if required.
        EventLog.WriteEntry("安装数据库",ex.Message,EventLogEntryType.Error) ;
        throw new InstallException(ex.Message);
       }
      }
     
      /**//// <summary>
      /// 插入数据
      /// </summary>
      /// <returns></returns>
      public bool InsertDate()
      {
       try
       {
        ExecuteScripts("configroot/Files/Insert/File");
        EventLog.WriteEntry("安装数据库","记录增加完成");
        return true;
       }
       catch(Exception ex)
       {
        //Customize if required.
        EventLog.WriteEntry("安装数据库",ex.Message,EventLogEntryType.Error) ;
        throw new InstallException(ex.Message);
       }
      }
     
      /**//// <summary>
      /// 执行数据库脚本
      /// </summary>
      /// <param name="Xpath"></param>
      void ExecuteScripts(string Xpath)
      {
       XmlNodeList objectlist=null;
       ProcessStartInfo processInfo =new ProcessStartInfo("osql.exe");
       processInfo.WindowStyle=ProcessWindowStyle.Hidden;

       //Get the name of the file from the assembly's embedded resource.
       if(config !=null)
       {
        objectlist = config.SelectNodes(Xpath);
       }
       else
       {
        throw new InstallException("保存数据库脚本文件名称的XML文件不存在!");
       }

       foreach(XmlNode objectFile in objectlist)
       {
        //Get arguments
        processInfo.Arguments=GetCommonProcessArguments(objectFile.Attributes["name"].Value,databaseName);
        EventLog.WriteEntry("安装数据库",processInfo.Arguments);
        Process osql = Process.Start(processInfo);
        //Wait till it is done
        osql.WaitForExit();
        EventLog.WriteEntry( "安装数据库", objectFile.InnerText +" file executed..");
       }
      }

      /**//// <summary>
      /// 获得数据库脚本的完整路径
      /// </summary>
      /// <param name="fileName"></param>
      /// <returns></returns>
      private string GetFullPath(string fileName)
      {
       //The destination folder for this will be the Install\scripts folder under the
       //installation root
       //MessageBox.Show(targetPath + @"SqlScript\" + fileName);
       string FullPath = targetPath + @"SqlScript\" + fileName;
       return FullPath;
      }
     
      /**//// <summary>
      /// 读数据库脚本文件的内容
      /// </summary>
      /// <param name="filepath"></param>
      void PopulateDatabaseNamePlaceHolder(string filepath)
      {
       //Read the contents
       System.IO.StreamReader reader = new System.IO.StreamReader(filepath);  
       string content=reader.ReadToEnd();
       reader.Close();
       //Replace the placeholder with database name
       content =content.Replace(CONST_DATBASE_PLACEHOLDER,databaseName);
       //Writeback the contents
       System.IO.StreamWriter writer = new System.IO.StreamWriter(filepath,false);
       //MessageBox.Show(content);
       writer.Write(content);
       writer.Flush();
       writer.Close();
      }

      string GetCommonProcessArguments(string fileName, string overridendatabasename)
      {
       //是否是信任连接
       if(!trustedconnection)
       {
        /**//* Arguments configured.
          *  osql [-S server] [-d use database name]   [-U login id] [-P password]
          [-i inputfile]  [-o outputfile]
         */
        return " -S " + serverName + " -d " + overridendatabasename +" -U " + userName + " -P " +Password + " -i " + Char.ToString('"') +  GetFullPath(fileName) + Char.ToString('"') + " -o " + Char.ToString('"') + targetPath +  "Log.txt" + Char.ToString('"'); 
       }
       else
       {
        /**//* Arguments configured.
          *  osql [-S server] [-d use database name]   [-E trusted connection]
          [-i inputfile]  [-o outputfile]
         */
        return " -S " + serverName + " -d " + overridendatabasename + " -E " + " -i " + Char.ToString('"') +  GetFullPath(fileName) + Char.ToString('"') + " -o " + Char.ToString('"') + targetPath + "Log.txt" + Char.ToString('"'); 
       }
      }
     }
    }

    3.添加安装程序类文件WebSetupTest.cs 里面重载Install和Uninstall方法.
    public override void Install(IDictionary stateSaver)
      {
       bool TrustedConnection=false;
       base.Install (stateSaver);
       try
       {
        if(this.Context!=null)
        {
         StringDictionary parameters = Context.Parameters  ;
         string[] keys =new string[parameters.Count];
         parameters.Keys.CopyTo(keys,0);

         "把数据库\服务器名\数据库用户名\数据库密码\安装路径写进 stateSaver"#region "把数据库\服务器名\数据库用户名\数据库密码\安装路径写进 stateSaver"
         //MessageBox.Show(this.Context.Parameters["target"].ToString());
         stateSaver.Add("database",this.Context.Parameters["database"].ToString()); 
         stateSaver.Add("server",this.Context.Parameters["server"].ToString()); 
         stateSaver.Add("username",this.Context.Parameters["username"].ToString()); 
         stateSaver.Add("password",this.Context.Parameters["password"].ToString()); 
         stateSaver.Add("target",this.Context.Parameters["target"].ToString());
         #endregion

         //测试连接#region //测试连接
         //can encrypt here
         string connectionstring= "Data Source=" + stateSaver["server"].ToString() ;
         connectionstring+= ";Initial Catalog=" + stateSaver["database"].ToString() ;
         if(stateSaver["username"]!=null && stateSaver["username"].ToString().Length!=0)
         {
          SqlConnection conn =new SqlConnection( "server=" + stateSaver["server"].ToString()
           + ";database=master;Uid=" + stateSaver["username"].ToString() +";Password=" + stateSaver["password"].ToString());
          conn.Open();
          conn.Close();
          conn.Dispose();
          connectionstring+= ";User ID=" + stateSaver["username"].ToString() ;
          connectionstring+= ";Password=" + stateSaver["password"].ToString() ;
         }
         else
         {
          //信任连接
          SqlConnection conn =new SqlConnection( "Data Source=" + stateSaver["server"].ToString()
           + ";Initial Catalog=master;trusted_connection=yes");
          conn.Open();
          conn.Close();
          conn.Dispose();
          TrustedConnection=true;
          stateSaver.Add("trustedconnection",true);
          connectionstring+=";Trusted_connection=yes";
         }
         #endregion

         //把数据库连接字符串写进web.config文件.#region //把数据库连接字符串写进web.config文件.
         XmlDocument doc = new XmlDocument();
         doc.Load(stateSaver["target"].ToString()+ @"Web.config");
         XmlNode connectionNode = doc.SelectSingleNode(@"configuration/appSettings/add[@key='Conn_WebSetupTest']");
         if(connectionNode!=null)
         {
          connectionNode.Attributes["value"].Value = connectionstring;
          doc.Save( stateSaver["target"].ToString()+ @"Web.config");
          EventLog.WriteEntry("安装数据","Configuration file processed"); //写日志
         }
         else
         {
          //This error will ensure installation is uncomplete
          throw new InstallException("没有数据库连接串!");
         }
         #endregion
         //执行数据库脚本,安装数据库#region //执行数据库脚本,安装数据库
         DataBase dbInstall =null;
         if(TrustedConnection)
         { 
          dbInstall= new DataBase(stateSaver["server"].ToString(),stateSaver["database"].ToString(),
           stateSaver["target"].ToString());
         }
         else
         {
          dbInstall= new DataBase(stateSaver["server"].ToString(),stateSaver["database"].ToString(),
           stateSaver["username"].ToString(),stateSaver["password"].ToString(),stateSaver["target"].ToString());
         }
         dbInstall.CreateDataBase();
         dbInstall.InsertDate();
         #endregion

         //部署桌面快捷方式*******************#region//部署桌面快捷方式*******************
         StreamWriter sw2=System.IO.File.CreateText(Context.Parameters["des"].ToString()+"WebSetupTest.url");
         stateSaver.Add("DeskQuick",Context.Parameters["des"].ToString()+"WebSetupTest.url"); //保存桌面快诫方式文件绝对地址
         //Context.Parameters["des"].ToString()是对应的桌面地址
         string webdirs=Context.Parameters["webdir"].ToString();
         //Context.Parameters["webdir"].ToString()对应的路径,在安装项目里面作为参数传入
         string webdirsNew = webdirs.Substring(0,webdirs.Length-1);
         webdirs = webdirsNew.Substring(webdirsNew.LastIndexOf(@"\")+1);
         string Urls=@"URL=http://localhost/"+webdirs+@"/index.aspx";
         sw2.WriteLine("[InternetShortcut]");
         sw2.WriteLine(Urls);
         sw2.WriteLine("modified=228928983");
         sw2.WriteLine("IconIndex=0");
         //sw2.WriteLine("IconFile="+webdirsNew+"\\Resources\\usa_folder_dialup.ico");
         sw2.WriteLine("IconFile="+webdirsNew+"\\images\\usa_folder_dialup.ico");
         sw2.Flush();
         sw2.Close();
         #endregion

         部署开始菜单 ***************#region 部署开始菜单 ***************
         string startMenue=Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);
         if(File.Exists(startMenue+"\\WebSetupTest.url"))
         {
          if(MessageBox.Show("开始菜单已经存在,是否有覆盖它?","安装开始菜单",MessageBoxButtons.YesNo,MessageBoxIcon.Question,
           MessageBoxDefaultButton.Button1) == DialogResult.Yes)
          {
                        
           File.Copy(Context.Parameters["des"].ToString()+"WebSetupTest.url",startMenue+"\\WebSetupTest.url",true);
          }
          else
          {
           throw new InstallException("开始菜单已经存在,安装取消");
          }
         }
         else
         {
          File.Copy(Context.Parameters["des"].ToString()+"WebSetupTest.url",startMenue+"\\WebSetupTest.url",false);
         }
         stateSaver.Add("StartMenueFile",startMenue+"\\WebSetupTest.url"); //保存开始菜单文件绝对地址
         #endregion
        }
       }
       catch(Exception ex1)
       {
        throw new System.Configuration.Install.InstallException(ex1.ToString());
       }
      }

      public override void Uninstall(IDictionary savedState)
      {
       try
       {
        if(savedState!=null)
        {
         base.Uninstall (savedState);

         删除快捷键,删除开始菜单#region 删除快捷键,删除开始菜单
         //删除快捷键
         if(File.Exists(savedState["DeskQuick"].ToString()))
         {
          File.Delete(savedState["DeskQuick"].ToString());
         }
         //删除开始菜单
         if(File.Exists(savedState["StartMenueFile"].ToString()))
         {
          File.Delete(savedState["StartMenueFile"].ToString());
         }
         #endregion

         //删除数据库#region //删除数据库
         if(MessageBox.Show("要删除数据库吗?" +savedState["database"].ToString()+".\n ","确认删除数据库",MessageBoxButtons.YesNo,MessageBoxIcon.Question  ,MessageBoxDefaultButton.Button2)== DialogResult.No)    
         {
          return;
         }
         DataBase dbInstall=null;
         if(savedState["trustedconnection"]!=null && (bool)savedState["trustedconnection"])
         {
          dbInstall= new DataBase(savedState["server"].ToString(),savedState["database"].ToString(),
           savedState["target"].ToString());
         }
         else
         {
          dbInstall= new DataBase(savedState["server"].ToString(),savedState["database"].ToString(),
           savedState["username"].ToString(),savedState["password"].ToString(),savedState["target"].ToString());
         }
         dbInstall.DropDataBase();
         #endregion
        }
        else
        {
         MessageBox.Show("Saved state was nullsome error.");
         throw new ApplicationException("卸载需要的参数不存在!");
        }
       }
       catch(InstallException inst)
       {
        throw new InstallException(inst.Message);
       }
       catch(Exception generic)
       {
        throw new InstallException(generic.Message);
       }
      }

    (四)在同一解决方案里添加'Web安装项目"WebSetup

    1.打开"文件系统"视图
    (1)"web应用程序文件夹"-->右键"添加"-->"项目输出" 选择"WebSetupTest"里的"主输出"和"内容文件",如下图:

    主输出一般是dll文件,内容文件包括aspx文件\web.config\images目录等等.

    (2)"web应用程序文件夹"--新建目录"install",然后"install"右键"项目输出" 选择"WebSetupLib"里的"主输出"和"内容文件"

    2.打开"用户界面"视图.
    (1)."安装"--"启动"-->右键"添加对话完"--"许可协议".
    添加完毕后在"许可协议"的"属性窗口"中添加刚才的UserProtocol.rtf文件.
    (2).用上面一样的方法添加"文本框(A)",在其属性里设置服务器和数据库信息


    下图是上面是两个对话框添加完毕后的"用户界面"视图.

    3.打开"自定义操作"视图.

    (1)"安装"-->右键"添加自定义操作"选择"install"目录下的"主输出来自WebSegtupLib",命名为Install
    它是设置自定义的数据/快捷方式/开菜单等.


    (2)在上面的install属性窗口里"CustomActionData"的值为/server=[SERVER_NAME] /target="[TARGETDIR]\" /database=[DATABASE_NAME] /username=[USER_NAME] /password=[PASSWORD] /version=[WINDOWSVERSION] /des="[DesktopFolder]\" /webdir="[TARGETDIR]\"

    (3)"卸载"--右键"添加自定义操作"选择"install"目录下的"主输出来自WebSegtupLib".命名为UnInstall
    这样卸载的时候将删除数据库/快捷方式/开菜单等.下图是两个子定义操作后的"自定义操作"视图.


    4."启动条件"视图使用默认值.
    五.编译安装项目

    编译后将生成WebSetup.msi安装文件.这样就可以安装了.下面是安装效果图




    六.参考资料

    自定义 MSI 安装(里面有详细的数据库部署代码实例)
    http://www.netscum.dk/china/msdn/library/langtool/vsdotnet/usvs04j7.mspx

  • 相关阅读:
    [Effective JavaScript 笔记]第54条:将undefined看做“没有值”
    [Effective JavaScript 笔记]第53条:保持一致的约定
    UDP打洞原理介绍
    Uboot启动分析之Start.S
    MMU
    linux_shell
    SSH2配置
    线程同步
    C#线程基础
    客户端服务器通讯常用的一种方法——Marshal类
  • 原文地址:https://www.cnblogs.com/freeliver54/p/1139083.html
Copyright © 2011-2022 走看看