最近在開發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站點,刪除數據庫等。