上接    WCF学习之旅—WCF服务部署到IIS7.5(九)

WCF学习之旅—WCF服务部署到应用程序(十)

七 WCF服务的Windows 服务程序寄宿

这种方式的服务寄宿,和IIS一样有一个一样的优点,系统启动后,WCF服务也会跟着启动了,不用人工干预,也是一种较好的寄宿方式。

(1) 在解决方案下新建控制台输出项目 WinServiceHosting。如下图。

(2)添加 System.ServiceModel.dll 的引用。

(3)添加 WCF 服务类库(WcfServiceLib)的项目引用。

(4) 添加响应的Window服务类。如下图。

(5)然后在服务类启动里面添加WCF的寄宿代码,如下所示。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.ServiceModel;
  8. using System.ServiceProcess;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11.  
  12. namespace WinSvrviceHosting
  13. {
  14. partial class WCFServiceMgr : ServiceBase
  15. {
  16. string Name = "WCF服务Windows Service寄宿";
  17. public WCFServiceMgr()
  18. {
  19.  
  20. InitializeComponent();
  21. this.ServiceName = Name;
  22. }
  23.  
  24. protected override void OnStart(string[] args)
  25. {
  26. // TODO: 在此处添加代码以启动服务。
  27.  
  28. try
  29. {
  30. svrHost = new ServiceHost(typeof(WCFServiceMgr));
  31. if (svrHost.State != CommunicationState.Opened)
  32. {
  33. svrHost.Open();
  34. }
  35. }
  36.  
  37. catch (Exception ex)
  38. {
  39. Logger.Log(ex,string.Empty,string.Empty,string.Empty);
  40.  
  41. }
  42.  
  43. Logger.Log(Name + DateTime.Now.ToShortTimeString() + "已成功调用了服务一次。");
  44. Logger.Log(Name + "已成功启动。");
  45. }
  46.  
  47. protected override void OnStop()
  48. {
  49. // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
  50. if (svrHost!=null)
  51. {
  52. svrHost.Close();
  53. svrHost = null;
  54.  
  55. }
  56. }
  57.  
  58. private static object syncRoot = new Object();//同步锁
  59. private ServiceHost svrHost = null; //寄宿服务对象
  60.  
  61. }
  62.  
  63. }

(6) 在WCFServiceMgr.cs的设计界面上右键,在弹出菜单中选择“添加安装程序”。如下图1。这时,项目里会自动生成一个ProjectInstaller.cs文件。如下图2。

图1

图2

( 7) 选中serviceInstaller1,打开它的属性视图,修改属性。如下图所示:

(8) 接着选中serviceProcessInstaller1,打开它的属性视图,修改属性。如下图:(这里服务账号也可以是其他的。)

(9) 为了实现通过该控制台程序实现参数化安装和卸载服务,我们需要拦截控制台的参数,并进行相应的操作,如下所示。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration.Install;
  4. using System.Linq;
  5. using System.ServiceProcess;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace WinSvrviceHosting
  10.  
  11. {
  12.  
  13. class Program
  14.  
  15. {
  16. static void Main(string[] args)
  17. {
  18.  
  19. ServiceController service = new ServiceController(WCFServiceMgr.Name);
  20.  
  21. // 运行服务
  22.  
  23. if (args.Length == )
  24. {
  25.  
  26. ServiceBase[] ServicesToRun;
  27. ServicesToRun = new ServiceBase[] { new WCFServiceMgr() };
  28. ServiceBase.Run(ServicesToRun);
  29. }
  30.  
  31. else if (args[].ToLower() == "/i" || args[].ToLower() == "-i")
  32. {
  33.  
  34. #region 安装服务
  35.  
  36. if (!IsServiceExisted("WCFServiceMgr"))
  37. {
  38. try
  39.  
  40. {
  41.  
  42. string[] cmdline = { };
  43.  
  44. string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
  45. TransactedInstaller transactedInstaller = new TransactedInstaller();
  46. AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
  47. transactedInstaller.Installers.Add(assemblyInstaller);
  48.  
  49. transactedInstaller.Install(new System.Collections.Hashtable());
  50. TimeSpan timeout = TimeSpan.FromMilliseconds( * );
  51. service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout);
  52. }
  53.  
  54. catch (Exception ex)
  55. { Logger.Log(ex,string.Empty,string.Empty,string.Empty);
  56. throw ex;
  57.  
  58. }
  59. }
  60.  
  61. #endregion
  62.  
  63. }
  64. else if (args[].ToLower() == "/u" || args[].ToLower() == "-u")
  65.  
  66. {
  67.  
  68. #region 删除服务
  69.  
  70. try
  71. {
  72.  
  73. if (IsServiceExisted("WCFServiceMgr"))
  74. {
  75.  
  76. string[] cmdline = { };
  77. string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
  78.  
  79. TransactedInstaller transactedInstaller = new TransactedInstaller();
  80. AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
  81. transactedInstaller.Installers.Add(assemblyInstaller);
  82. transactedInstaller.Uninstall(null);
  83. }
  84. }
  85.  
  86. catch (Exception ex)
  87. {
  88. Logger.Log(ex, string.Empty, string.Empty, string.Empty);
  89. throw ex;
  90. }
  91. #endregion
  92. }
  93.  
  94. }
  95.  
  96. #region 检查服务存在的存在性
  97.  
  98. /// <summary>
  99. /// 检查服务存在的存在性
  100. /// </summary>
  101. /// <param name=" NameService ">服务名</param>
  102. /// <returns>存在返回 true,否则返回 false;</returns>
  103. public static bool IsServiceExisted(string NameService)
  104. {
  105. ServiceController[] services = ServiceController.GetServices();
  106. foreach (ServiceController s in services)
  107. {
  108. if (s.ServiceName.ToLower() == NameService.ToLower())
  109. {
  110. return true;
  111. }
  112. }
  113. return false;
  114. }
  115.  
  116. #endregion
  117.  
  118. }
  119.  
  120. }

(10)添加应用程序配置文件App.config,这次我们使用配置的方式进行WCF服务的公布,WCF服务配置代码如下。

  1. <?xml version="1.0" encoding="utf-8" ?>
  2.  
  3. <configuration>
  4.  
  5. <startup>
  6.  
  7. <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  8.  
  9. </startup>
  10.  
  11. <system.serviceModel>
  12.  
  13. <diagnostics>
  14.  
  15. <messageLogging logEntireMessage="true" logKnownPii="false" logMalformedMessages="true"
  16. logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
  17. <endToEndTracing propagateActivity="true" activityTracing="true"
  18.  
  19. messageFlowTracing="true" />
  20. </diagnostics>
  21.  
  22. <behaviors>
  23. <serviceBehaviors>
  24. <behavior name="metadataBehavior">
  25. <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8080/BookService/metadata" />
  26. <serviceDebug includeExceptionDetailInFaults="True" />
  27. </behavior>
  28.  
  29. </serviceBehaviors>
  30.  
  31. </behaviors>
  32.  
  33. <services>
  34.  
  35. <service behaviorConfiguration="metadataBehavior" name="WcfServiceLib.BookService">
  36.  
  37. <endpoint address="http://127.0.0.1:8080/BookService" binding="wsHttpBinding"
  38.  
  39. contract="WcfServiceLib.IBookService" />
  40.  
  41. </service>
  42.  
  43. </services>
  44.  
  45. </system.serviceModel>
  46.  
  47. </configuration>

(11) 编译程序成功后,我们添加两个批处理的DOS脚本来实现执行程序的自动安装和卸载,如下所示。

  1. --安装脚本
  2.  
  3. "WinSvrviceHosting.exe" -i
  4.  
  5. pause
  1. --卸载脚本
  2.  
  3. "WinSvrviceHosting.exe" -u
  4.  
  5. Pause
  1. (12) 我们首先执行安装脚本。结果如下图。

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

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

   建立客户端

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

WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)的更多相关文章

  1. WCF学习之旅—WCF服务部署到IIS7.5(九)

    上接   WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...

  2. WCF学习之旅—WCF服务部署到应用程序(十)

    上接  WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...

  3. WCF学习之旅—WCF服务的WAS寄宿(十二)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...

  4. WCF学习之旅—WCF服务的批量寄宿(十三)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) WCF学习之旅—WCF ...

  5. WCF学习之旅—WCF第二个示例(五)

    二.WCF服务端应用程序 第一步,创建WCF服务应用程序项目 打开Visual Studio 2015,在菜单上点击文件—>新建—>项目—>WCF服务应用程序.在弹出界面的“名称”对 ...

  6. WCF学习之旅—WCF第二个示例(七)

    三.创建客户端应用程序 若要创建客户端应用程序,你将另外添加一个项目,添加对该项目的服务引用,配置数据源,并创建一个用户界面以显示服务中的数据. 在第一个步骤中,你将 Windows 窗体项目添加到解 ...

  7. WCF学习之旅—WCF第二个示例(六)

    第五步,创建数据服务 在“解决方案资源管理器”中,使用鼠标左键选中“SCF.WcfService”项目,然后在菜单栏上,依次选择“项目”.“添加新项”. 在“添加新项”对话框中,选择“Web”节点,然 ...

  8. WCF学习之旅—WCF寄宿前的准备(八)

    一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类协定的定 ...

  9. WCF学习之旅—WCF概述(四)

    一.WCF概述 1) 什么是WCF? Windows Communication Foundation (WCF) 是用于构建面向服务的应用程序的框架.借助 WCF,可以将数据作为异步消息从一个服务终 ...

随机推荐

  1. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  2. DailyTick 开发实录 —— 开始

    2009 年我读了李笑来老师的<把时间当朋友>,知识了柳比歇夫的时间记录法.当时激动坏了,马上动手实践起来.一开始的时候,是用一个小本子,走到哪儿都带着.完成一件事,就记录一下花费的时间. ...

  3. ASP.NET Aries 入门开发教程7:DataGrid的行操作(主键操作区)

    前言: 抓紧勤奋,再接再励,预计共10篇来结束这个系列. 上一篇介绍:ASP.NET Aries 入门开发教程6:列表数据表格的格式化处理及行内编辑 本篇介绍主键操作区相关内容. 1:什么时候有默认的 ...

  4. Ngrok让你的本地Web应用暴露在公网上

    1.Ngrok介绍 Ngrok是一个反向代理,通过在公共的端点和本地运行的Web服务器之间建立一个安全的通道.Ngrok可捕获和分析所有通道上的流量,便于后期分析和重放.简单来说,利用 Ngrok可以 ...

  5. 步入angularjs directive(指令)--准备工作熟悉hasOwnProperty

    在讲解directive之前,先做一下准备工作,为何要这样呢? 因为我们不是简单的说说directive怎么用,还要知道为什么这么用!(今天我们先磨磨刀!). 首先我们讲讲js 基础的知识--hasO ...

  6. ,net core mvc 文件上传

    工作用到文件上传的功能,在这个分享下 ~~ Controller: public class PictureController : Controller { private IHostingEnvi ...

  7. Javascript高性能编程-提高Dom访问速度

    在浏览器中对于Dom的操作和普通的脚本的操作处于两个不同的dll中,两个dll的交互是比较耗时的,优化对Dom的操作可以提高脚本的执行速度.下面是对如何优化的一些总结: 将需要多次操作的节点存储在一个 ...

  8. TCP/IP基础

    TCP/IP 是用于因特网 (Internet) 的通信协议. 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述. 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的 ...

  9. 在将 varchar 值 'xinpian' 转换成数据类型 int 时失败?

    把int类型的值修改为varchar类型的值

  10. 两个变量交换的四种方法(Java)

    对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...