C#打包--如何用VS2005制作Web安装程序(上)

C#打包--如何用VS2005制作Web安装程序(上)

 
网站完成后,需要部署到目标机器上,方法有很多,直接把文件Copy到目标机器上,执行SQL脚本,配置IIS,这样可以做到;也可以使用InstallShield这样到专业制作软件来打包。本篇文章是使用VS2005自带到安装部署工具来制作exe安装文件。
 
涉及到到内容包括:使用安装部署工具,建立数据库,配置IIS,文件操作,注册表等。参考了网上关于使用VS制作安装程序的文章。环境:Windows2003 + VS2005 + SQL2005。
 
注:本文只是为了实现,没有强调方法,变量等的写法标准。
 
使用VS2005制作安装程序的时候,有多种选择,如下图:
 
C#打包--如何用VS2005制作Web安装程序(上)

我想一般常用的可能就最上面的两种。当使用Web安装项目时,执行制作好的msi安装文件时,会发现实际上是添加虚拟目录而不是添加网站,而且无法选择安装目录,当然,可以自己写脚本来对IIS进行修改。不过在这篇文章里,将不采用此模式。本篇文章用的是使用“安装项目”,就和打包WinForm程序一样,把Web文件部署到目标机器上,然后重写install方法,配置IIS,执行SQL脚本,修改web.config文件等。
 
在开始整个过程之前,需要先了解一下“预编译”的概念,MSDN上的说明是:默认情况下,在用户首次请求资源(如网站的一个页)时,将动态编译 ASP.NET 网页和代码文件。第一次编译页和代码文件之后,会缓存编译后的资源,这样将大大提高随后对同一页提出的请求的效率。请查阅MSDN“预编译”相关文档。
 
准备一个文件DBSQL.txt,在里面包含连接数据库后需要执行的SQL脚本,在本例中使用了简单的一个Create Tabel的SQL。
 
好了,现在开干,吼吼~~~~~~~~~~
 
打开VS2005,打开一个网站项目,这里是打开的本地localhost,如图:
 
C#打包--如何用VS2005制作Web安装程序(上)

新加一个页面,随便取个名字(本文中为ClientCallback.aspx),然后写一个简单的按钮事件即可,这不是本文的重点,由你随意处理^_^ 再添加web配置文件即web.config,在下添加
             
此文件到时候是需要发布到目标机器上的。(关于连接数据库字符串,VS2005里面有专门的connectionStrings,本文未使用,可查阅帮助)
 
点击生成网站,访问页面,ok!
 
选择菜单生成=》发布网站:
 
C#打包--如何用VS2005制作Web安装程序(上)

点击确定后,网站已经生成,这些就是需要部署到目标机器上的所有文件。
 
点击菜单文件=》添加=》新建项目,添加安装部署项目,如图:
 
C#打包--如何用VS2005制作Web安装程序(上)

添加安装项目类库:
 
C#打包--如何用VS2005制作Web安装程序(上)

删除默认的Class1.cs,新加一个安装程序类文件,名为MyInstaller.cs:
 
C#打包--如何用VS2005制作Web安装程序(上)

 
在此项目中,添加对System.EnterpriseServices和System.DirectoryServices的引用,在操作IIS的时候,需要用到。在文件中添加:
 
using System;

using System.IO;

using System.DirectoryServices;

using System.Reflection;

using System.Data;

using System.Data.SqlClient;

using System.Configuration.Install;

using System.Management;

using System.Collections;

using Microsoft.Win32;

using System.Collections.Specialized;

 

如果编译的时候出错,请添加相关引用。
 
修改文件如下图:
 
C#打包--如何用VS2005制作Web安装程序(上)

 
注意要手动添加Installer!
 
将DBSQL.txt文件放到此项目中,在属性中设置为“嵌入的资源”
 
C#打包--如何用VS2005制作Web安装程序(上)

回到MyWebSetup项目,点击查看属性,可以设置安装文件到显示相关信息,如图
 
C#打包--如何用VS2005制作Web安装程序(上)

选择文件系统,如图:
 
C#打包--如何用VS2005制作Web安装程序(上)

然后:
 
C#打包--如何用VS2005制作Web安装程序(上)

(在文件系统中,在属性里面可以设置安装程序默认到安装路径)
 
添加一个叫bin文件夹并添加在生成网站时bin目录下的dll文件,如图:
 
C#打包--如何用VS2005制作Web安装程序(上)

在应用程序文件夹下在生成网站时目录下的文件,添加后如图:
 
C#打包--如何用VS2005制作Web安装程序(上)

 
选择“用户界面编辑器”,添加两个文本框A和B,A将作为安装新站点后的IIS设置,B将作为数据库操作时的参数设置,调整位置后如下:
 
C#打包--如何用VS2005制作Web安装程序(上)

调整A的属性,这里只选择了显示两个输入框,属性分别为IISSERVER和PORT,值为localhost和9998,其他的你可以自己调整。如图:
 
C#打包--如何用VS2005制作Web安装程序(上)
文本框B的设置如下:
C#打包--如何用VS2005制作Web安装程序(上)
OK,文本框设置完毕。当然,你还可以选择其他的多种文本框,如协议什么的。
打开自定义操作面板:
C#打包--如何用VS2005制作Web安装程序(上)

C#打包--如何用VS2005制作Web安装程序(上)

然后:
 
C#打包--如何用VS2005制作Web安装程序(上)

在CustomActionData中输入:
/dbname=[DBNAME] /server=[DBSERVERNAME] /user=[USERNAME] /pwd=[PASSWORD] /iis=[IISSERVER] /port=[PORT] /targetdir="[TARGETDIR]"
这些参数就是文本框A和B上的输入框的值,在安装过程中可以获得,然后进行处理。
至此,基本的安装文件已经制作完毕。进行生成,然后点击安装,可以看到文件已经复制到了相应到目录。接下来就要接收参数对IIS和数据库进行处理。
打开SetupClassLibrary项目下的MyInstaller.Designer.cs,修改此文件。
申明几个变量:  
 private System.Data.SqlClient.SqlConnection sqlConn;

        private System.Data.SqlClient.SqlCommand Command;

        private string DBName;

        private string ServerName;

        private string AdminName;

        private string AdminPwd;

    

        private string iis;

        private string port;

        private string dir;

        public static string VirDirSchemaName = "IIsWebVirtualDir";

        private string _target;

        private DirectoryEntry _iisServer;

        private ManagementScope _scope;

        private ConnectionOptions _connection;
连接数据库服务器到方法:
#region ConnectDatabase 连接数据库

        private bool ConnectDatabase()

        {

            if (Command.Connection.State != ConnectionState.Open)

            {

                try

                {

                    Command.Connection.Open();

                }

                catch(Exception e)

                {

                    return false;

                }

            }

            return true;

        }

        #endregion
如果不能正确连接数据库服务器,请检查你的连接字符串,或者将连接字符串写入文件查看。不好意思,我不知道如何对这种安装部署程序进行debug,sorry咯!
读取SQL文件的方法:
#region GetSql 从文件中读取SQL,在读取包含SQL脚本的文件时需要用到,参考自MSDN

        private string GetSql(string Name)

        {

            try

            {

                Assembly Asm = Assembly.GetExecutingAssembly();

                Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name);

                StreamReader reader = new StreamReader(strm);

                return reader.ReadToEnd();

            }

            catch (Exception getException)

            {

                throw new ApplicationException(getException.Message);

            }

        }

        #endregion
可以将此需要执行的SQL脚本放在此文本中
执行SQL语句的方法:
#region ExecuteSql 执行SQL语句,参考自MSDN

        private void ExecuteSql(string DataBaseName, string sqlstring)

        {

            Command = new System.Data.SqlClient.SqlCommand(sqlstring, sqlConn);

            if (ConnectDatabase())

            {

                try

                {

                    Command.Connection.ChangeDatabase(DataBaseName);

                    Command.ExecuteNonQuery();

                }

                finally

                {

                   Command.Connection.Close();

                }

            }

        }

        #endregion
创建数据库及数据库表:
#region CreateDBAndTable 创建数据库及数据库表,参考自MSDN

        protected bool CreateDBAndTable(string DBName)

        {

           

            bool Restult = false;

            try

            {

                ExecuteSql("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE " + DBName);

                ExecuteSql("master", "CREATE DATABASE " + DBName);

                ExecuteSql(DBName, GetSql("DBSQL.txt"));

               

                Restult = true;

            }

            Catch

           

            {

            }

            return Restult;

        }

        #endregion
从备份文件恢复数据库及数据库表
#region RestoreDB 从备份文件恢复数据库及数据库表

        ///

        /// 从备份文件恢复数据库及数据库表

        ///

        /// 数据库名

        /// 配件中数据库脚本资源的名称

        ///

        protected bool RestoreDB(string DBName)

        {

            dir = this.Context.Parameters["targetdir"];

            bool Restult = false;

            string MSQL = "RESTORE DATABASE " + DBName +

                " FROM DISK = '" + dir + @"data.bak' " +

                " WITH MOVE 'Test' TO '" + @"c:" + DBName + ".mdf', " +

                " MOVE 'Test_log' TO '" + @"c:" + DBName + ".ldf' ";

            try

            {

                ExecuteSql("master", "USE MASTER IF EXISTS (SELECT NAME FROM SYSDATABASES WHERE NAME='" + DBName + "') DROP DATABASE " + DBName);

                ExecuteSql("master", MSQL);

                Restult = true;

            }

            finally

            {

                // 删除备份文件

                try

                {

                    File.Delete(dir + @"data.bak");

                }

                catch

                {

                }

            }

            return Restult;

        }

        #endregion
这里可以到注册表读取SQL Server的安装路径,把恢复后的数据库文件放到data目录地下。在本例中,只是实现了恢复,并未进行标准的操作。其中Test和Test_log时备份时数据库的文件信息。如果想要从备份文件中恢复,请把文件包含到项目里并且设置和DBSQL.txt一样,嵌入到程序里。最后执行删除。不过我想应该有办法不把文件先安装到目标机器上,而是有方法想读取DBSQL.txt文件一样,直接恢复数据库,不过确实没想到办法,失败!
 
网站安装好后,需要设置web.config文件,这里只涉及到连接字符串到设置,其他的可以同理修改。     
#region WriteWebConfig 修改web.config的连接数据库的字符串

        private bool WriteWebConfig()

        {

            System.IO.FileInfo FileInfo = new System.IO.FileInfo(this.Context.Parameters["targetdir"] + "/web.config");

            if (!FileInfo.Exists)

            {

                throw new InstallException("Missing config file :" + this.Context.Parameters["targetdir"] + "/web.config");

            }

            System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();

            xmlDocument.Load(FileInfo.FullName);

            bool FoundIt = false;

            foreach (System.Xml.XmlNode Node in xmlDocument["configuration"]["appSettings"])

            {

                if (Node.Name == "add")

                {

                    if (Node.Attributes.GetNamedItem("key").Value == "ConnectionString")

                    {

                        Node.Attributes.GetNamedItem("value").Value = String.Format("Persist Security Info=False;Data Source={0};database={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", ServerName, DBName, AdminName, AdminPwd);

                        FoundIt = true;

                    }

                }

            }

            if (!FoundIt)

            {

                throw new InstallException("Error when writing the config file: web.config");

            }

            xmlDocument.Save(FileInfo.FullName);

            return FoundIt;

        }

        #endregion
posted @ 2020-12-02 14:27  昶·Cc  阅读(201)  评论(0编辑  收藏  举报