你的位置:首页 > ASP.net教程

[ASP.net教程]WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)


上接    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服务配置代码如下。

<??><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" -ipause

 

--卸载脚本"WinSvrviceHosting.exe" -uPause


(12) 我们首先执行安装脚本。结果如下图。

 

        (13) 顺利执行脚本后,“管理工具—》服务”,在服务列表里面就增加一个服务项目了。如下图。

 

        (14) 执行卸载脚本,脚本就会卸载服务。如下图。

 

 

   建立客户端

      使用我们在Console寄宿程序编写的客户端,去访问Windows窗体宿主程序的WCF服务。