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

<?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服务。

 

 

 

posted @ 2016-05-24 15:11  DotNet菜园  阅读(4722)  评论(4编辑  收藏  举报