C# 使用打包工具实现web应用一键发布

来源:互联网 发布:物流软件app是什么意思 编辑:程序博客网 时间:2024/06/05 18:37
                   **Web应用的一键发布程序**前段时间刚到公司上班,上级给了一个任务用于试用期测试和转正述职前提。需求如下:制作一个web应用的一键发布发布程序,要求能自动检测安装IIS,应用所需插件,还原数据库(sql server)备份文件和执行更新SQL。先说一下我的思路:由于我们公司的客户都试用WINDOWS的系统,我们开发工具是vs2015。所以我最想到的就是利用支持VS的打包工具来实现将系统界面和我自定义界面结合来实现这个安装程序。我最先使用的是VS开发工具建议使用的InstallShield-Limited-Edition这个打包插件。研究了一下发现这个插件的界面比较的美观也有一定的用户自定义功能,各种定制选项也比较完善;但是我发现他不能实现用户自定义界面(例如:WinForm)和工具所提供的见面组合,无法满足我的要求最后放弃了。后来改用了微软自己的打包工具visual studio installer这个工具能够实现我的所有需求。这个工具安装完成之后VS工具里面就会出现相应的工程。[如图](http://img.blog.csdn.net/20170725164849927?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzA2OTcwMTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 有了这个东东之后我们就可以开始接下来的操作了!!首先需要创建一个安装工程,如上图这个工具可以打包桌面应用程序,也可以打包发布WEB应用。由于我所发布的程序的特殊性(混合程序),我就选用了桌面应用程序的(Setup project)。最基础的自定义要求如图[这里写图片描述](http://img.blog.csdn.net/20170725170700378?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzA2OTcwMTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast),这个工具的使用方式你们可以参考一下这位道友的文章(http://www.cnblogs.com/daban/archive/2012/06/27/2565449.html)。自定义安装程序你需要2个最基础的工程第一个当然就是 安装打包工程(Setup project);另一个是自定义界面和处理逻辑需要使用的类库工程(创建最普通的类库工程就好)然后删除点里面的默认class.cs文件,新建一个安装类。如图[就是他](http://img.blog.csdn.net/20170725172115114?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzA2OTcwMTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)这个类就是系统的安装逻辑和你自定义的逻辑连接的中间点。在这个类里面你可以自定义安装,修复,卸载。。。。所需要使用的特殊逻辑和界面。这个类的具体使用方法我就不详细说明了,网上一大推说明。![安装描述](http://img.blog.csdn.net/20170725172840560?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzA2OTcwMTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 如图就是我在系统安装步骤结束之后打开了一个我自定义的界面,后面的步骤就是同学们最熟悉的WINFORM工程的操作了。 我列举一下比较重要的功能点代码:

1:IIS的检测以及添加网站、应用池、重启指定网站等等

 using Microsoft.Web.Administration;using System;using System.Collections.Generic;using System.DirectoryServices;using System.Linq;namespace SetupLibrary{    /// <summary>    /// IIS 操作方法集合    /// http://blog.csdn.net/ts1030746080/article/details/8741399 错误    /// </summary>    public class IISTools    {        private static string HostName = "localhost";        /// <summary>        /// 获取本地IIS版本        /// </summary>        /// <returns></returns>        public static string GetIIsVersion()        {            try            {                DirectoryEntry entry = new DirectoryEntry("IIS://" + HostName + "/W3SVC/INFO");                string version = entry.Properties["MajorIISVersionNumber"].Value.ToString();                return version;            }            catch (Exception se)            {                //说明一点:IIS5.0中没有(int)entry.Properties["MajorIISVersionNumber"].Value;属性,将抛出异常 证明版本为 5.0                return string.Empty;            }        }        /// <summary>        /// 创建虚拟目录网站        /// </summary>        /// <param name="webSiteName">网站名称</param>        /// <param name="physicalPath">物理路径</param>        /// <param name="domainPort">站点+端口,如192.168.1.23:90</param>        /// <param name="isCreateAppPool">是否创建新的应用程序池</param>        /// <returns></returns>        public static int CreateWebSite(string webSiteName, string physicalPath, string domainPort, bool isCreateAppPool)        {            DirectoryEntry root = new DirectoryEntry("IIS://" + HostName + "/W3SVC");            // 为新WEB站点查找一个未使用的ID            int siteID = 1;            foreach (DirectoryEntry e in root.Children)            {                if (e.SchemaClassName == "IIsWebServer")                {                    int ID = Convert.ToInt32(e.Name);                    if (ID >= siteID) { siteID = ID + 1; }                }            }            // 创建WEB站点            DirectoryEntry site = (DirectoryEntry)root.Invoke("Create", "IIsWebServer", siteID);            site.Invoke("Put", "ServerComment", webSiteName);            site.Invoke("Put", "KeyType", "IIsWebServer");            site.Invoke("Put", "ServerBindings", domainPort + ":");            site.Invoke("Put", "ServerState", 2);            site.Invoke("Put", "FrontPageWeb", 1);            site.Invoke("Put", "DefaultDoc", "Default.html");            // site.Invoke("Put", "SecureBindings", ":443:");            site.Invoke("Put", "ServerAutoStart", 1);            site.Invoke("Put", "ServerSize", 1);            site.Invoke("SetInfo");            // 创建应用程序虚拟目录            DirectoryEntry siteVDir = site.Children.Add("Root", "IISWebVirtualDir");            siteVDir.Properties["AppIsolated"][0] = 2;            siteVDir.Properties["Path"][0] = physicalPath;            siteVDir.Properties["AccessFlags"][0] = 513;            siteVDir.Properties["FrontPageWeb"][0] = 1;            siteVDir.Properties["AppRoot"][0] = "LM/W3SVC/" + siteID + "/Root";            siteVDir.Properties["AppFriendlyName"][0] = "Root";            if (isCreateAppPool)            {                DirectoryEntry apppools = new DirectoryEntry("IIS://" + HostName + "/W3SVC/AppPools");                DirectoryEntry newpool = apppools.Children.Add(webSiteName, "IIsApplicationPool");                newpool.Properties["AppPoolIdentityType"][0] = "4"; //4                newpool.Properties["ManagedPipelineMode"][0] = "1"; //0:集成模式 1:经典模式                newpool.CommitChanges();                siteVDir.Properties["AppPoolId"][0] = webSiteName;            }            siteVDir.CommitChanges();            site.CommitChanges();            return siteID;        }        /// <summary>        /// 得到网站的物理路径        /// </summary>        /// <param name="rootEntry">网站节点</param>        /// <returns></returns>        public static string GetWebsitePhysicalPath(DirectoryEntry rootEntry)        {            string physicalPath = "";            foreach (DirectoryEntry childEntry in rootEntry.Children)            {                if ((childEntry.SchemaClassName == "IIsWebVirtualDir") && (childEntry.Name.ToLower() == "root"))                {                    if (childEntry.Properties["Path"].Value != null)                    {                        physicalPath = childEntry.Properties["Path"].Value.ToString();                    }                    else                    {                        physicalPath = "";                    }                }            }            return physicalPath;        }        /// <summary>        /// 获取站点名        /// </summary>        public static List<IISInfo> GetServerBindings()        {            List<IISInfo> iisList = new List<IISInfo>();            string entPath = String.Format("IIS://{0}/w3svc", HostName);            DirectoryEntry ent = new DirectoryEntry(entPath);            foreach (DirectoryEntry child in ent.Children)            {                if (child.SchemaClassName.Equals("IIsWebServer", StringComparison.OrdinalIgnoreCase))                {                    if (child.Properties["ServerBindings"].Value != null)                    {                        object objectArr = child.Properties["ServerBindings"].Value;                        string serverBindingStr = string.Empty;                        if (IsArray(objectArr))//如果有多个绑定站点时                        {                            object[] objectToArr = (object[])objectArr;                            serverBindingStr = objectToArr[0].ToString();                        }                        else//只有一个绑定站点                        {                            serverBindingStr = child.Properties["ServerBindings"].Value.ToString();                        }                        IISInfo iisInfo = new IISInfo();                        iisInfo.DomainPort = serverBindingStr;                        iisInfo.webname = child.Properties["ServerComment"].Value.ToString();                        iisInfo.AppPool = child.Properties["AppPoolId"].Value.ToString();//应用程序池                        iisList.Add(iisInfo);                    }                }            }            return iisList;        }        /// <summary>        /// 建立程序池后关联相应应用程序及虚拟目录        /// </summary>        public static void SetAppToPool(string appname, string poolName)        {            //获取目录            DirectoryEntry getdir = new DirectoryEntry("IIS://localhost/W3SVC");            foreach (DirectoryEntry getentity in getdir.Children)            {                if (getentity.SchemaClassName.Equals("IIsWebServer"))                {                    //设置应用程序程序池 先获得应用程序 在设定应用程序程序池                    //第一次测试根目录                    foreach (DirectoryEntry getchild in getentity.Children)                    {                        if (getchild.SchemaClassName.Equals("IIsWebVirtualDir"))                        {                            //找到指定的虚拟目录.                            foreach (DirectoryEntry getsite in getchild.Children)                            {                                if (getsite.Name.Equals(appname))                                {                                    //【测试成功通过】                                    getsite.Properties["AppPoolId"].Value = poolName;                                    getsite.CommitChanges();                                }                            }                        }                    }                }            }        }        /// <summary>        /// 根据IIS站点名称重启网站        /// </summary>        /// <param name="sitename"></param>        public static void RestartWEbSite(string sitename)        {            try            {                var server = new ServerManager();                var site = server.Sites.FirstOrDefault(s => s.Name == sitename);                if (site != null)                {                    site.Stop();                    if (site.State == ObjectState.Stopped)                    {                    }                    else                    {                    }                    site.Start();                }                else                {                }            }            catch (Exception e)            {                Console.WriteLine(e);            }        }        /// <summary>        /// 判断object对象是否为数组        /// </summary>        public static bool IsArray(object o)        {            return o is Array;        }    }    /// <summary>    /// 应用池类    /// </summary>    public class IISInfo    {        public string DomainPort { set; get; }        public string AppPool { set; get; }        public string webname { get; set; }    }}  
2.IIS的安装 IIS的安装有点烦,我弄了好久。主要是在网上找的方法所安装的IIS 都有缺陷,最主要的一个就是安装的时候不能默认安装IIS6兼容性功能模块,会导致上面IIS工具类无法正常使用,最后妥协了使用了批处理命令来安装。
    @echo offecho install iis start /w pkgmgr /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASPNET;IIS-NetFxExtensibility;IIS-ASP;IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-ServerSideIncludes;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-ODBCLogging;IIS-Security;IIS-BasicAuthentication;IIS-WindowsAuthentication;IIS-DigestAuthentication;IIS-ClientCertificateMappingAuthentication;IIS-IISCertificateMappingAuthentication;IIS-URLAuthorization;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-WebServerManagementTools;IIS-ManagementConsole;IIS-ManagementScriptingTools;IIS-ManagementService;IIS-IIS6ManagementCompatibility;IIS-Metabase;IIS-WMICompatibility;IIS-LegacyScripts;IIS-LegacySnapIn;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPIecho install flashpause

3 . 还原数据库备份(bak文件) 和执行SQL脚本文件
我所采用的方式是直接使用sqlcommand工具类执行还原的SQL语句
RESTORE DATABASE “+ dbName + ” from DISK =“+dbpath+”WITH REPLACE

   SQL 脚本文件我所使用的方式是利用osql命令:                                      osql -S 服务器 -U 用户名 -P 密码 -d 数据库 -i \"SQL文件路径\"" 

4.插件的检测
我使用的是最基础的注册表检测,这个我就不多说啦。

我写这个目的是为了对一些以前不了解的东西做一些保留,也希望能帮到你们。以我写的这个东西的可读性和连贯性我估计也帮不到几个人。。。。。。。。

原创粉丝点击