最近在开发web网站安装部署,以前从来没有做过web的安装打包没有头绪就开始上网查资料。
查了两天资料发现网上的资料要么不全要么就有错误,我就总结了网上的资料重新整理的一番,经过本人测试可用无错误
一下为借鉴部分资料的原文地址
此链接为打包ASP.NET网站资料(这个资料有问题,在自定义操作哪一步详情看下面文章):http://www.cnblogs.com/fish520/archive/2016/09/22/5882450.html
此链接为创建IIS站点(其中代码不全我还借鉴的部分其他论坛的资料):http://www.cnblogs.com/wujy/archive/2013/02/28/2937667.html
首先开始的是文件打包
第一步创建安装项目
第二步添加主输出(右键安装项目)
选择网站
第三步设置用户界面
点击添加对话框
选择许可文件、文本框A、文本框B顺序按下面顺序排列
第四步添加许可协议文件
右键安装项目点击视图=》文件系统
选择应用程序文件夹=》右键点击=》文件
选择创建好的*.rtf文件即可,该文件打开wrod另存为rtf格式文件即可
我们回到用户界面
右键许可协议=》属性=》设置licenseFile属性选择文件为刚刚添加的文件
在安装过程中我们要添加附加数据库和创建IIS站点所以需要用到数据的账号密码和创建IIS的相关信息
我们右键文本框A=》属性
设置下面参数,第四个用不上隐藏了
创建IIS需要的相关信息在文本框B填写
右键文本框B=》属性
用户填写上面创建IIS需要的相关信息,其中添加的默认值是因为不能为空否则会报错
接下来我们创建一个安装类库,创建IIS和附加数据库将在该类库中完成
右键解决方案=》添加类库
然后右键创建好的该类库=》添加安装程序类
接下里右键安装文件添加项目输出
选择刚刚添加的安装类点确定
接下来右键安装项目=》视图=》自定义操作
右键安装=》添加自定义操作=选择web应用程序文件夹
选择刚刚添加的安装类点击确定
然后右键安装下面的主输出文件=》点击属性
设置CustomActionData的值
/server=[EDITA1] /user=[EDITA2] /pwd=[EDITA3] /iis=[IISSERVER] /ip=[IP] /port=[PORT] /isname=[isname] /targetdir="[TARGETDIR]\"
设置这些中括号[]括起来的就是文本框的ID在用户界面中的文本框属性中设置
我在文章开头写的那个借鉴资料中的一篇文在这里的设置中写错了他用双引号和单引号把后面的值引起来之后在创建IIS站点的时候报错了,这个错误纠结了我一下午的时间去查资料,最后把项目拷出来放在一个aspx页面中错误的那一块一句句的调试才找到原因
我们回到那个安装类upLibrary1右键查看安装文件类的代码
好了。上面就是文件打包的全部过程了,下面我们接下来就是创建网站的IIS站点和附加网站的数据库
创建IIS站点
以下为需要引用的命名空间
using System.IO;
using System.Data.SqlClient;
using System.Management;
using System.Security.AccessControl;
using System.DirectoryServices;
using Microsoft.Web.Administration;
using System.Diagnostics;
using System.Windows.Forms;
//iis服务器地址下面方法会用到所以定义公共 string iis = ""; //重写Install public override void Install(IDictionary stateSaver) { base.Install(stateSaver); //接收参数 //数据库服务器地址 string databaseServer = Context.Parameters["server"].ToString(); //账号 string user = Context.Parameters["user"].ToString(); //密码 string pwd = Context.Parameters["pwd"].ToString(); //安装路径 string targetdir = Context.Parameters["targetdir"].ToString().Replace(@"\\", @"\"); //IIS地址 iis = this.Context.Parameters["iis"].ToString(); //ip string ip = this.Context.Parameters["ip"].ToString(); //端口 string port = this.Context.Parameters["port"].ToString(); //网站名 string isname = this.Context.Parameters["isname"].ToString(); //File.WriteAllText(Path.Combine(targetdir, "log11.txt"), "databaseServer:" + databaseServer + "/n/r" + "user:" + user + "/n/r" + "pwd:" + pwd + "/n/r" + "targetdir:" + targetdir + "/n/r" + "iis:" + iis + "/n/r" + "port:" + port + "/n/r" + "isname" + isname + "/n/r" + "serverID:" + serverID); try { //实例化IIS站点配置信息 NewWebSiteInfo nwsif = new NewWebSiteInfo(ip, port, isname.Trim(), (isname.Trim().Length > 0 ? isname : "anjiesigudingzichan"), targetdir); //创建IIS站点 CreateNewWebSite(nwsif); #region 附加数据库 //给文件添加"Authenticated Users,Everyone,Users"用户组的完全控制权限 ,要附加的数据库文件必须加权限否则无法附加 if (File.Exists(Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.mdf")) { FileInfo fi = new FileInfo(Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.mdf"); System.Security.AccessControl.FileSecurity fileSecurity = fi.GetAccessControl(); fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow)); fileSecurity.AddAccessRule(new FileSystemAccessRule("Authenticated Users", FileSystemRights.FullControl, AccessControlType.Allow)); fileSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow)); fi.SetAccessControl(fileSecurity); FileInfo fi1 = new FileInfo(Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.ldf"); System.Security.AccessControl.FileSecurity fileSecurity1 = fi1.GetAccessControl(); fileSecurity1.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow)); fileSecurity1.AddAccessRule(new FileSystemAccessRule("Authenticated Users", FileSystemRights.FullControl, AccessControlType.Allow)); fileSecurity1.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow)); fi1.SetAccessControl(fileSecurity1); } string connectionString = GetConnectionString(null); //保存数据连接词,为卸载做准备 File.WriteAllText(Path.Combine(targetdir + "\\" + "App_Data\\", "log.txt"), connectionString); try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); //使用数据库文件创建数据库,所以添加的网站项目中需要有App_Data文件夹和数据库文件(ceshi.mdf)和日志文件(ceshi.ldf) string sql = "sp_attach_db ‘ceshi‘,‘" + Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.mdf‘,‘" + Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.ldf‘"; ExecuteSQL(connection, sql); connection.Close(); //修改config文件连接词 string webconfigpath = Path.Combine(this.Context.Parameters["targetdir"].ToString(), "web.config"); string webcofnigstring = File.ReadAllText(webconfigpath).Replace("#constring#", GetConnectionString("ceshi")); File.WriteAllText(webconfigpath, webcofnigstring); } } catch (Exception ex) { MessageBox.Show("安装出错了1!\n" + ex.ToString(), "出错啦!"); } #endregion } catch (Exception exx) { MessageBox.Show("安装出错了!2\n" + exx.ToString(), "出错啦!"); } } /// <summary> /// 执行SQL语句 /// </summary> /// <param name="connection"></param> /// <param name="sql"></param> void ExecuteSQL(SqlConnection connection, string sql) { SqlCommand cmd = new SqlCommand(sql, connection); cmd.ExecuteNonQuery(); } /// <summary> /// 获取数据库登陆连接字符串 /// </summary> /// <param name="databasename"></param> /// <returns></returns> private string GetConnectionString(string databasename) { return "server=" + Context.Parameters["server"].ToString() + ";database=" + (string.IsNullOrEmpty(databasename) ? "master" : databasename) + ";User ID=" + Context.Parameters["user"].ToString() + ";Password=" + Context.Parameters["pwd"].ToString(); } /// <summary> /// 创建IIS站点 /// </summary> /// <param name="siteInfo">新站点配置信息</param> public void CreateNewWebSite(NewWebSiteInfo siteInfo) { string entPath = String.Format("IIS://{0}/W3SVC", iis); //SetFileRole(); if (!EnsureNewSiteEnavaible(siteInfo.BindString, entPath)) { throw new Exception("该网站已存在" + Environment.NewLine + siteInfo.BindString); } DirectoryEntry rootEntry = new DirectoryEntry(entPath); string newSiteNum = GetNewWebSiteID(entPath); DirectoryEntry newSiteEntry = rootEntry.Children.Add(newSiteNum, "IIsWebServer"); newSiteEntry.CommitChanges(); newSiteEntry.Properties["ServerBindings"].Value = siteInfo.BindString; newSiteEntry.Properties["ServerComment"].Value = siteInfo.CommentOfWebSite; newSiteEntry.Properties["ServerAutoStart"].Value = true;//网站是否启动 newSiteEntry.CommitChanges(); DirectoryEntry vdEntry = newSiteEntry.Children.Add("root", "IIsWebVirtualDir"); vdEntry.CommitChanges(); string ChangWebPath = siteInfo.WebPath.Trim().Remove(siteInfo.WebPath.Trim().LastIndexOf(‘\\‘), 1); vdEntry.Properties["Path"].Value = ChangWebPath; vdEntry.Invoke("AppCreate", true);//创建应用程序 //vdEntry.Properties["ServerAutoStart"].Value = true;//网站是否启动 vdEntry.Properties["AccessRead"][0] = true; //设置读取权限 vdEntry.Properties["AccessWrite"][0] = true; vdEntry.Properties["AccessScript"][0] = true;//执行权限 vdEntry.Properties["AccessExecute"][0] = false; vdEntry.Properties["DefaultDoc"][0] = "Login_gdzc.aspx";//设置默认文档 vdEntry.Properties["AppFriendlyName"][0] = "LabManager"; //应用程序名称 vdEntry.Properties["AuthFlags"][0] = 1;//0表示不允许匿名访问,1表示就可以3为基本身份验证,7为windows继承身份验证 vdEntry.CommitChanges(); //操作增加MIME //IISOle.MimeMapClass NewMime = new IISOle.MimeMapClass(); //NewMime.Extension = ".xaml"; NewMime.MimeType = "application/xaml+xml"; //IISOle.MimeMapClass TwoMime = new IISOle.MimeMapClass(); //TwoMime.Extension = ".xap"; TwoMime.MimeType = "application/x-silverlight-app"; //rootEntry.Properties["MimeMap"].Add(NewMime); //rootEntry.Properties["MimeMap"].Add(TwoMime); //rootEntry.CommitChanges(); #region 针对IIS7 DirectoryEntry getEntity = new DirectoryEntry("IIS://" + iis + "/W3SVC/INFO"); int Version = int.Parse(getEntity.Properties["MajorIISVersionNumber"].Value.ToString()); if (Version > 6) { #region 创建应用程序池 string AppPoolName = "LabManager"; if (!IsAppPoolName(AppPoolName)) { DirectoryEntry newpool; DirectoryEntry appPools = new DirectoryEntry("IIS://" + iis + "/W3SVC/AppPools"); newpool = appPools.Children.Add(AppPoolName, "IIsApplicationPool"); newpool.CommitChanges(); } #endregion #region 修改应用程序的配置(包含托管模式及其NET运行版本) ServerManager sm = new ServerManager(); sm.ApplicationPools[AppPoolName].ManagedRuntimeVersion = "v4.0"; sm.ApplicationPools[AppPoolName].ManagedPipelineMode = ManagedPipelineMode.Classic; //托管模式Integrated为集成 Classic为经典 sm.CommitChanges(); #endregion vdEntry.Properties["AppPoolId"].Value = AppPoolName; vdEntry.CommitChanges(); } #endregion //启动aspnet_regiis.exe程序 string fileName = Environment.GetEnvironmentVariable("windir") + @"\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe"; ProcessStartInfo startInfo = new ProcessStartInfo(fileName); //处理目录路径 string path = vdEntry.Path.ToUpper(); int index = path.IndexOf("W3SVC"); path = path.Remove(0, index); //启动ASPnet_iis.exe程序,刷新脚本映射 startInfo.Arguments = "-s " + path; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; Process process = new Process(); process.StartInfo = startInfo; process.Start(); process.WaitForExit(); string errors = process.StandardError.ReadToEnd(); if (errors != string.Empty) { throw new Exception(errors); } } #region 判定网站是否存在 /// <summary> /// 确定一个新的网站与现有的网站没有相同的。 /// 这样防止将非法的数据存放到IIS里面去 /// </summary> /// <param name="bindStr">网站邦定信息</param> /// <returns>真为可以创建,假为不可以创建</returns> public bool EnsureNewSiteEnavaible(string bindStr, string entPath) { DirectoryEntry ent = new DirectoryEntry(entPath); foreach (DirectoryEntry child in ent.Children) { if (child.SchemaClassName == "IIsWebServer" && child.Properties["ServerBindings"].Value != null && child.Properties["ServerBindings"].Value.ToString() == bindStr) { return false; } } return true; } /// <summary> /// 设置文件夹权限 处理给EVERONE赋予所有权限 /// </summary> /// <param name="FileAdd">文件夹路径</param> public void SetFileRole() { string FileAdd = this.Context.Parameters["targetdir"].ToString(); FileAdd = FileAdd.Remove(FileAdd.LastIndexOf(‘\\‘), 1); DirectorySecurity fSec = new DirectorySecurity(); fSec.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); System.IO.Directory.SetAccessControl(FileAdd, fSec); } #endregion
IIS站点信息类
/// <summary> /// IIS站点配置信息 /// </summary> public class NewWebSiteInfo { private string hostIP; // 主机IP private string portNum; // 网站端口号 private string descOfWebSite; // 网站表示。一般为网站的网站名。例如"www.dns.com.cn" private string commentOfWebSite;// 网站注释。一般也为网站的网站名。 private string webPath; // 网站的主目录。例如"e:\ mp" /// <summary> /// 实例化IIS站点配置 /// </summary> /// <param name="hostIP">主机IP</param> /// <param name="portNum">网站端口号</param> /// <param name="descOfWebSite">网站表示。一般为网站的网站名。例如"www.dns.com.cn"--【主机名(域名)】</param> /// <param name="commentOfWebSite">网站注释。一般也为网站的网站名。--【iis网站站点名称】</param> /// <param name="webPath">网站的主目录。例如"e:\ mp"</param> public NewWebSiteInfo(string hostIP, string portNum, string descOfWebSite, string commentOfWebSite, string webPath) { this.hostIP = hostIP; this.portNum = portNum; this.descOfWebSite = descOfWebSite; this.commentOfWebSite = commentOfWebSite; this.webPath = webPath; } /// <summary> /// 网站标识 /// </summary> public string BindString { get { return String.Format("{0}:{1}:{2}", hostIP, portNum, descOfWebSite); //网站标识(IP,端口,主机头值) } } /// <summary> /// 网站端口号 /// </summary> public string PortNum { get { return portNum; } } /// <summary> /// 网站表示。一般为网站的网站名。例如"www.dns.com.cn" /// </summary> public string CommentOfWebSite { get { return commentOfWebSite; } } /// <summary> /// 网站的主目录。例如"e:\ mp" /// </summary> public string WebPath { get { return webPath; } } }
删除应用池还没测试过,可以放在卸载里面。我还没写卸载
/// <summary> /// 删除指定程序池 /// </summary> /// <param name="AppPoolName">程序池名称</param> /// <returns>true删除成功 false删除失败</returns> private bool DeleteAppPool(string AppPoolName) { bool result = false; DirectoryEntry appPools = new DirectoryEntry("IIS://localhost/W3SVC/AppPools"); foreach (DirectoryEntry getdir in appPools.Children) { if (getdir.Name.Equals(AppPoolName)) { try { getdir.DeleteTree(); result = true; } catch { result = false; } } } return result; }
这是我从网上资料总结出来整个asp.net安装打包流程,包括的IIS站点的创建和数据库附加。
卸载我还没写,有兴趣的可以写下卸载,删除应用池删除IIS站点,删除数据库等。