上接 WCF學習之旅—WCF服務部署到IIS7.5(九) WCF學習之旅—WCF服務部署到應用程式(十) 七 WCF服務的Windows 服務程式寄宿 這種方式的服務寄宿,和IIS一樣有一個一樣的優點,系統啟動後,WCF服務也會跟著啟動了,不用人工干預,也是一種較好的寄宿方式。 (1) 在解決方案下 ...
上接 WCF學習之旅—WCF服務部署到IIS7.5(九)
WCF學習之旅—WCF服務部署到應用程式(十)
七 WCF服務的Windows 服務程式寄宿
這種方式的服務寄宿,和IIS一樣有一個一樣的優點,系統啟動後,WCF服務也會跟著啟動了,不用人工干預,也是一種較好的寄宿方式。
(1) 在解決方案下新建控制台輸出項目 WinServiceHosting。如下圖。
(2)添加 System.ServiceModel.dll 的引用。
(3)添加 WCF 服務類庫(WcfServiceLib)的項目引用。
(4) 添加響應的Window服務類。如下圖。
(5)然後在服務類啟動裡面添加WCF的寄宿代碼,如下所示。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace WinSvrviceHosting
{
partial class WCFServiceMgr : ServiceBase
{
string Name = "WCF服務Windows Service寄宿";
public WCFServiceMgr()
{
InitializeComponent();
this.ServiceName = Name;
}
protected override void OnStart(string[] args)
{
// TODO: 在此處添加代碼以啟動服務。
try
{
svrHost = new ServiceHost(typeof(WCFServiceMgr));
if (svrHost.State != CommunicationState.Opened)
{
svrHost.Open();
}
}
catch (Exception ex)
{
Logger.Log(ex,string.Empty,string.Empty,string.Empty);
}
Logger.Log(Name + DateTime.Now.ToShortTimeString() + "已成功調用了服務一次。");
Logger.Log(Name + "已成功啟動。");
}
protected override void OnStop()
{
// TODO: 在此處添加代碼以執行停止服務所需的關閉操作。
if (svrHost!=null)
{
svrHost.Close();
svrHost = null;
}
}
private static object syncRoot = new Object();//同步鎖
private ServiceHost svrHost = null; //寄宿服務對象
}
}
(6) 在WCFServiceMgr.cs的設計界面上右鍵,在彈出菜單中選擇“添加安裝程式”。如下圖1。這時,項目里會自動生成一個ProjectInstaller.cs文件。如下圖2。
圖1
圖2
( 7) 選中serviceInstaller1,打開它的屬性視圖,修改屬性。如下圖所示:
(8) 接著選中serviceProcessInstaller1,打開它的屬性視圖,修改屬性。如下圖:(這裡服務賬號也可以是其他的。)
(9) 為了實現通過該控制台程式實現參數化安裝和卸載服務,我們需要攔截控制台的參數,併進行相應的操作,如下所示。
using System; using System.Collections.Generic; using System.Configuration.Install; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; namespace WinSvrviceHosting { class Program { static void Main(string[] args) { ServiceController service = new ServiceController(WCFServiceMgr.Name); // 運行服務 if (args.Length == 0) { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new WCFServiceMgr() }; ServiceBase.Run(ServicesToRun); } else if (args[0].ToLower() == "/i" || args[0].ToLower() == "-i") { #region 安裝服務 if (!IsServiceExisted("WCFServiceMgr")) { try { string[] cmdline = { }; string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location; TransactedInstaller transactedInstaller = new TransactedInstaller(); AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline); transactedInstaller.Installers.Add(assemblyInstaller); transactedInstaller.Install(new System.Collections.Hashtable()); TimeSpan timeout = TimeSpan.FromMilliseconds(1000 * 10); service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout); } catch (Exception ex) { Logger.Log(ex,string.Empty,string.Empty,string.Empty); throw ex; } } #endregion } else if (args[0].ToLower() == "/u" || args[0].ToLower() == "-u") { #region 刪除服務 try { if (IsServiceExisted("WCFServiceMgr")) { string[] cmdline = { }; string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location; TransactedInstaller transactedInstaller = new TransactedInstaller(); AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline); transactedInstaller.Installers.Add(assemblyInstaller); transactedInstaller.Uninstall(null); } } catch (Exception ex) { Logger.Log(ex, string.Empty, string.Empty, string.Empty); throw ex; } #endregion } } #region 檢查服務存在的存在性 /// <summary> /// 檢查服務存在的存在性 /// </summary> /// <param name=" NameService ">服務名</param> /// <returns>存在返回 true,否則返回 false;</returns> public static bool IsServiceExisted(string NameService) { ServiceController[] services = ServiceController.GetServices(); foreach (ServiceController s in services) { if (s.ServiceName.ToLower() == NameService.ToLower()) { return true; } } return false; } #endregion } }
(10)添加應用程式配置文件App.config,這次我們使用配置的方式進行WCF服務的公佈,WCF服務配置代碼如下。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> <system.serviceModel> <diagnostics> <messageLogging logEntireMessage="true" logKnownPii="false" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" /> <endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" /> </diagnostics> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8080/BookService/metadata" /> <serviceDebug includeExceptionDetailInFaults="True" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="metadataBehavior" name="WcfServiceLib.BookService"> <endpoint address="http://127.0.0.1:8080/BookService" binding="wsHttpBinding" contract="WcfServiceLib.IBookService" /> </service> </services> </system.serviceModel> </configuration>
(11) 編譯程式成功後,我們添加兩個批處理的DOS腳本來實現執行程式的自動安裝和卸載,如下所示。
--安裝腳本 "WinSvrviceHosting.exe" -i pause
--卸載腳本 "WinSvrviceHosting.exe" -u Pause
(12) 我們首先執行安裝腳本。結果如下圖。
(13) 順利執行腳本後,“管理工具—》服務”,在服務列表裡面就增加一個服務項目了。如下圖。
(14) 執行卸載腳本,腳本就會卸載服務。如下圖。
建立客戶端
使用我們在Console寄宿程式編寫的客戶端,去訪問Windows窗體宿主程式的WCF服務。