zoukankan      html  css  js  c++  java
  • (转)制作web安装程序 dodo


    出处:http://www/i-blog.cn/u/chenli/archives/2006/8.html

    本文参考http://blog.csdn.net/libra1983/archive/2006/09/25/1274933.aspx

    1、1.  打开VS2005,创建一个新的工程,选择:其他项目类型->安装和部署->安装项目。名称为Setup,确定。

    2、2.    在文件系统中加入要安装的所有文件和文件夹。可在应用程序文件夹节点上单击鼠标右键,选择添加文件或文件夹。这里注意,如果要添加的文件夹中还有子文件夹这样添加会有点麻烦。可以先选择应用程序文件夹,在资源管理器中选择所有要安装的文件和文件夹,直接将选择的文件和文件夹拖放到VS2005的应用程序文件夹中(VS2005此时中间的部分)。

    3、 3.   添加一个新项目,这里选择Visual C#的类库。用来在安装过程中添加MS Sql Server数据库,以及在IIS中创建网站。命名为SetupClassLibrary,确定。

    4、4.    在安装数据库时,会执行脚本。在SetupClassLibrary项目中加入一个名为DBSQL.txt的文件,将要执行的脚本放在里面。将该文件的属性中生成操作属性设为:嵌入的资源。注意该脚本只是创建表和存储过程等,不是创建数据库的,而且不要含有“GO”命令,如果有“GO”命令可以用替换的方法把“GO”换成空白。

    5、5.    删除SetupClassLibrary中自动生成的Class1.cs。在SetupClassLibrary中添加新的项。选择安装程序类。命名为SetupInstaller.cs,确定。

    6、6.    SetupInstaller.cs的代码试图中可以看到SetupInstaller类继承自Installer。这里要重写Installer的几个方法,来处理安装过程中的行为。

    7、7.    重写InstallerInstall方法。该方法在安装时执行。还可以重写Commit(完成)Rollback(回滚)Uninstall(卸载)SetupInstaller.cs中所有的代码在附录中。可以直接复制过来。需要添加的引用有:System.DirectoryServices。然后编译这个项目。

            public override void Install(IDictionary stateSaver)

            {

                base.Install(stateSaver);

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

                DBName = this.Context.Parameters["DBNAME"].ToString();

                ServerName = this.Context.Parameters["DBSERVERNAME"].ToString();

                AdminName = this.Context.Parameters["USERNAME"].ToString();

                AdminPwd = this.Context.Parameters["PASSWORD"].ToString();

                iis = this.Context.Parameters["IISSERVER"].ToString(); 

                port = this.Context.Parameters["PORT"].ToString();

                //写入获取的安装程序中的变量,此段代码为调试用可以不添加

                this.sqlConn.ConnectionString = "Packet size=4096;User ID=" + AdminName + ";Data Source=" + ServerName + ";Password=" + AdminPwd + ";Persist Security Info=False;Integrated Security=false";

                // 执行SQL 安装数据库可选择时恢复或者时直接创建

                if (!CreateDBAndTable(DBName))

                {

                    throw new ApplicationException("创建数据库时出现严重错误!");

                }

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

                /*

                if (!RestoreDB(DBName))

                {

                    throw new ApplicationException("恢复数据库时出现严重错误!");

                }

                */

     

                // 添加网站

                Connect();

                //string serverID = GetNextOpenID().ToString();

                //string serverComment = websitenName;

                // 下面的信息为测试,可以自己编写文本框来接收用户输入信息

                string serverID = "5555";

                string serverComment = "PortalSite";

                string defaultVrootPath = this.Context.Parameters["targetdir"];

                if (defaultVrootPath.EndsWith(@"\"))

                {

                    defaultVrootPath = defaultVrootPath.Substring(0, defaultVrootPath.Length - 1);

                }

                string HostName = "";

                string IP = "";

                string Port = port;

                string sReturn = CreateWebSite(serverID, serverComment, defaultVrootPath, HostName, IP, Port);

                // 修改web.config

                //if (!WriteWebConfig())

                //{

                //    throw new ApplicationException("设置数据库连接字符串时出现错误");

                //}

                // 写注册表

                //WriteRegistryKey();

            }

    8、8.    在安装项目Setup中打开用户界面编辑器,这里要在安装向导中加入设置数据库以及IIS的地方。在启动节点单击鼠标右键,添加对话框,把文本框(A)和文本框(B)都添加进来。把他们拖到确认安装的上面。

    9、9.    设置文本框(A)的属性。BodyText:输入新网站的设置;Edit1Label:服务器;Edit1PropertyIISSERVEREdit1localhostEdit2Label:端口;Edit2PropertyPORTEdit29998Edit3VisibleFalseEdit4VisibleFalse

    10.  设置文本框(B)的属性。BodyText:数据库设置;Edit1Label:数据库服务器;Edit1PropertyDBSERVERNAMEEdit1localhostEdit2Label:数据库名称;Edit2PropertyDBNAMEEdit2PortalEdit1Labe3:登录帐号;Edit3PropertyUSERNAME Edit4Label:密码;Edit4PropertyPASSWORD

    11              加入自定义的操作。在安装项目Setup中打开自定义操作编辑器。在安装节点单击鼠标右键,添加自定义操作。双击应用程序文件夹,点击添加程序集按钮,选择“浏览”页,找到并选择SetupClassLibrary项目生成的程序集SetupClassLibrary.dll,确定。安装节点下多了一个SetupClassLibrary.dll节点,在该节点单击鼠标右键,选择属性,设置CustomActionData属性为/DBNAME=[DBNAME] /DBSERVERNAME=[DBSERVERNAME] /USERNAME=[USERNAME] /PASSWORD=[PASSWORD] /IISSERVER=[IISSERVER] /PORT=[PORT] /TARGETDIR="[TARGETDIR]\"

    12.   先重新生成SetupClassLibrary项目,然后生成Setup项目。生成完毕后在Setup项目的Debug目录下可以找到Setup.msi文件和setup.exe文件。现在可以执行安装程序看看效果了。也可以在解决方案管理器的Setup项目节点上单击鼠标右键,选择安装。

     附录:SetupInstaller.cs的所有代码

    using System.DirectoryServices;
    using System.Management;
    using System.Collections;
    using System.Data;
    using System;
    using System.Reflection;
    using System.IO;
    using System.Configuration.Install;
    using Microsoft.Win32;
    using System.ComponentModel;


    namespace SetupClassLibrary
    {
        [RunInstaller(true)]
        public partial class SetupInstaller : Installer
        {
            public SetupInstaller()
            {
                InitializeComponent();
            }

            private System.Data.SqlClient.SqlConnection sqlConn=new System.Data.SqlClient.SqlConnection();

            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


            #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

            #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

            #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();

                xmlLoad(FileInfo.FullName);

                bool FoundIt = false;

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

                    if (Node.Name == "add")
                    {

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

                            Node.Attributes.GetNamedItem(""). = 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 web.config");

                }

                xmlSave(FileInfo.FullName);

                return FoundIt;

            }

            #endregion

            #region WriteRegistryKey 写注册表。安装部署中,直接有一个注册表编辑器,可以在那里面设置。

            private void WriteRegistryKey()
            {

                // 写注册表

                RegistryKey hklm = Registry.LocalMachine;

                RegistryKey cqfeng = hklm.OpenSubKey("SOFTWARE", true);

                RegistryKey F = cqfeng.CreateSubKey("cqfeng");

                F.Set("FilePath", "kkkk");

            }

            #endregion

            #region Connect 连接IIS服务器

            public bool Connect()
            {

                if (iis == null)

                    return false;

                try
                {

                    _iisServer = new DirectoryEntry("IIS://" + iis + "/W3SVC/1");

                    _target = iis;

                    _connection = new ConnectionOptions();

                    _scope = new ManagementScope(@"\\" + iis + @"\root\MicrosoftIISV2", _connection);

                    _scope.Connect();

                }

                catch
                {

                    return false;

                }

                return IsConnected();

            }

            public bool IsConnected()
            {

                if (_target == null || _connection == null || _scope == null) return false;

                return _scope.IsConnected;

            }

            #endregion

            #region IsWebSiteExists 判断网站是否已经存在

            public bool IsWebSiteExists(string serverID)
            {

                try
                {

                    string siteName = "W3SVC/" + serverID;

                    ManagementObjectSearcher searcher = new ManagementObjectSearcher(_scope, new ObjectQuery("SELECT * FROM IIsWebServer"), null);

                    ManagementObjectCollection webSites = searcher.Get();

                    foreach (ManagementObject webSite in webSites)
                    {

                        if ((string)webSite.Properties["Name"]. == siteName)

                            return true;

                    }

                    return false;

                }

                catch
                {

                    return false;

                }

            }

            #endregion

            #region GetNextOpenID 获得一个新的ServerID

            private int GetNextOpenID()
            {

                DirectoryEntry iisComputer = new DirectoryEntry("IIS://localhost/w3svc");

                int nextID = 0;

                foreach (DirectoryEntry iisWebServer in iisComputer.Children)
                {

                    string sname = iisWebServer.Name;

                    try
                    {

                        int name = int.Parse(sname);

                        if (name > nextID)
                        {

                            nextID = name;

                        }

                    }

                    catch
                    {

                    }

                }

                return ++nextID;

            }

            #endregion

            #region CreateWebsite 添加网站

            public string CreateWebSite(string serverID, string serverComment, string defaultVrootPath, string HostName, string IP, string Port)
            {

                try
                {

                    ManagementObject oW3SVC = new ManagementObject(_scope, new ManagementPath(@"IIsWebService='W3SVC'"), null);

                    if (IsWebSiteExists(serverID))
                    {

                        return "Site Already Exists...";

                    }

                    ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters("CreateNewSite");

                    ManagementBaseObject[] serverBinding = new ManagementBaseObject[1];

                    serverBinding[0] = CreateServerBinding(HostName, IP, Port);

                    inputParameters["ServerComment"] = serverComment;

                    inputParameters["ServerBindings"] = serverBinding;

                    inputParameters["PathOfRootVirtualDir"] = defaultVrootPath;

                    inputParameters["ServerId"] = serverID;

                    ManagementBaseObject outParameter = null;

                    outParameter = oW3SVC.InvokeMethod("CreateNewSite", inputParameters, null);

                    // 启动网站

                    string serverName = "W3SVC/" + serverID;

                    ManagementObject webSite = new ManagementObject(_scope, new ManagementPath(@"IIsWebServer='" + serverName + "'"), null);

                    webSite.InvokeMethod("Start", null);

                    return (string)outParameter.Properties["Return"].;

                }

                catch (Exception ex)
                {

                    return ex.Message;

                }

            }

            public ManagementObject CreateServerBinding(string HostName, string IP, string Port)
            {

                try
                {

                    ManagementClass classBinding = new ManagementClass(_scope, new ManagementPath("ServerBinding"), null);

                    ManagementObject serverBinding = classBinding.CreateInstance();

                    serverBinding.Properties["Hostname"]. = HostName;

                    serverBinding.Properties["IP"]. = IP;

                    serverBinding.Properties["Port"]. = Port;

                    serverBinding.Put();

                    return serverBinding;

                }

                catch
                {

                    return null;

                }

            }

            #endregion

            #region Install 安装

            ///

            /// 安装数据库

            ///

            ///
            public override void Install(IDictionary stateSaver)
            {
                base.Install(stateSaver);

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

                DBName = this.Context.Parameters["DBNAME"].ToString();

                ServerName = this.Context.Parameters["DBSERVERNAME"].ToString();

                AdminName = this.Context.Parameters["USERNAME"].ToString();

                AdminPwd = this.Context.Parameters["PASSWORD"].ToString();

                iis = this.Context.Parameters["IISSERVER"].ToString(); ;

                port = this.Context.Parameters["PORT"].ToString();

                //写入获取的安装程序中的变量,此段代码为调试用可以不添加

                this.sqlConn.ConnectionString = "Packet size=4096;User ID=" + AdminName + ";Data Source=" + ServerName + ";Password=" + AdminPwd + ";Persist Security Info=False;Integrated Security=false";

                // 执行SQL 安装数据库 可选择时恢复或者时直接创建
                if (!CreateDBAndTable(DBName))
                {
                    throw new ApplicationException("创建数据库时出现严重错误!");
                }

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

                /*

                if (!RestoreDB(DBName))

                {

                    throw new ApplicationException("恢复数据库时出现严重错误!");

                }

                */

                // 添加网站

                Connect();

                //string serverID = GetNextOpenID().ToString();

                //string serverComment = websitenName;

                // 下面的信息为测试,可以自己编写文本框来接收用户输入信息

                string serverID = "5555";

                string serverComment = "PortalSite";

                string defaultVrootPath = this.Context.Parameters["targetdir"];

                if (defaultVrootPath.EndsWith(@"\"))
                {

                    defaultVrootPath = defaultVrootPath.Substring(0, defaultVrootPath.Length - 1);

                }

                string HostName = "";

                string IP = "";

                string Port = port;

                string sReturn = CreateWebSite(serverID, serverComment, defaultVrootPath, HostName, IP, Port);


              
                // 修改web.config

                //if (!WriteWebConfig())
                //{

                //    throw new ApplicationException("设置数据库连接字符串时出现错误");

                //}

                // 写注册表

                //WriteRegistryKey();
            }

            #endregion

            #region Uninstall 删除

            public override void Uninstall(IDictionary savedState)
            {

                if (savedState == null)
                {

                    throw new ApplicationException("未能卸载!");

                }

                else
                {

                    base.Uninstall(savedState);

                }

            }

            #endregion

  • 相关阅读:
    Hz赫兹的定义
    NetCore 迅速接入微信支付+支付宝支付 payLink C# 交差并集
    C# 生产随机数 --几乎可以做到不重复
    Spark MLib完整基础入门教程
    (转)Scrapy 教程
    (转)python自顶向下设计步骤_python实现自顶向下,自底向上
    (转)scrapy架构图与执行流程
    (转)Python:字典(zip, dict)
    (转)APUE第13章 守护进程Deameon
    (转)Python开发指南
  • 原文地址:https://www.cnblogs.com/zgqys1980/p/558985.html
Copyright © 2011-2022 走看看