创建用于监视正在运行的Windows服务并与之交互的用户界面

我需要在我的服务器上的Windows服务中运行一堆可插入的进程,并希望创建一个用户界面,允许我与服务使用的每个插件进行交互。

用户界面和长时间运行的Windows服务之间通信的最常用方法是什么? 我正在考虑提供一个中间位置,如数据库,并使用某种消息队列向服务发出命令。 有没有人实施过这样的方法,或者其他一些优秀的方法? 你在这个过程中遇到了什么问题?

不要使用远程处理! 虽然它肯定会有效,但微软表示远程处理是一项传统技术,并且所有新的分布式应用程序都应该使用WCF开发。 有关详细信息,请参见此处

Windows Communication Foundation(WCF)是两个.NET进程相互通信的推荐方法。 WCF提供了一个统一的编程模型,通过抽象与特定通信机制相关的许多复杂性,例如套接字,管道等,大大简化了分布式开发。

鉴于您的情况的详细信息,我建议将每个Windows服务插件作为WCF服务。 对于每个WCF服务,即插件,定义它需要向UI公开的接口。 界面只是一个装有ServiceContract属性的C#界面。 此接口包含方法,每个方法都使用OperationContract属性进行装饰,您的UI将使用该方法与WCF服务(插件)进行通信。 这些方法可以接受并返回任何可序列化的.NET类型,或者通常是您自己的自定义类型。 要在WCF中使用自定义类型,只需使用DataContract属性修饰它们,并使用DataMember属性标记要通过WCF交换的成员。

一旦定义了ServiceContract接口,就定义一个实现该接口的类。 每个OperationContract方法都会执行它需要做的任何事情,例如,与数据库交互,计算某些值等。一旦完成此操作,您就已经有效地定义了WCF服务。 这是一个简短但有效的例子:

using System.ServiceModel; namespace AdditionServiceNamespace { [DataContract] public class Complex { [DataMember] public int real; [DataMember] public int imag; } [ServiceContract] public interface IAdditionService { [OperationContract] Complex Add(Complex c1, Complex c2); } public class AdditionService : IAdditionService { public Complex Add(Complex c1, Complex c2) { Complex result = new Complex(); result.real = c1.real + c2.real; result.imag = c1.imag + c2.imag; return result; } } } 

下一步是托管此WCF服务,以便UI可以使用它。 由于您将使用Windows服务,因此在Windows服务的OnStart()回调中可以轻松地托管您的WCF服务,如下所示:

 using System.ServiceModel; using System.ServiceProcess; using AdditionServiceNamespace; namespace WindowsServiceNamespace { public class WindowsService : ServiceBase { static void Main() { ServiceBase[] ServicesToRun = new ServiceBase[] { new WindowsService() }; ServiceBase.Run(ServicesToRun); } private ServiceHost _host; public WindowsService() { InitializeComponent(); } protected override void OnStart(string[] args) { _host = new ServiceHost(typeof(AdditionService)); _host.Open(); } protected override void OnStop() { try { if (_host.State != CommunicationState.Closed) { _host.Close(); } } catch { // handle exception somehow...log to event viewer, for example } } } } 

剩下要做的唯一事情是为Windows服务定义一个app.config文件,该文件将配置WCF服务的某些必需方面。 这似乎有点矫枉过正,但记住两件事。 首先,当您向项目添加WCF服务类时,Visual Studio会自动为您提供基本的app.config文件。 其次,app.config文件为您提供了对WCF服务的巨大控制,而无需更改代码。 这是上面示例的配套app.config文件:

             

无需更改代码! 进行更改,重新启动服务,您的WCF服务现在可供远程计算机使用。 如果需要,您甚至可以为同一个WCF服务允许多个端点。 关键是,app.config文件提供了极大的灵活性,而无需更改代码。

而已! 您现在可以在Windows服务中托管WCF服务,供UI使用。

那么UI方面(即客户端)如何工作?

这就是WCF的真正力量发挥作用的地方。 在开始使用WCF时,最简单的方法是利用Visual Studio的代码生成function。 确保您的Windows服务(托管AdditionService的服务)正在运行。 在UI项目中,右键单击解决方案资源管理器中的项目,然后选择“ 添加服务引用…”菜单选项。 在“ 地址”框中,键入net.pipe://localhost/AdditionService ,然后单击“ Go”按钮。 您应该会看到AdditionService显示在“ 服务”列表中。 在“ 命名空间”框中,键入AdditionService ,然后单击“ 确定”按钮。

执行这些步骤将生成一个客户端代理和一个正确定义的app.config文件,该文件将添加到您的UI项目中。 此客户端代理成为您的客户端AdditionService API,您可以像这样使用它:

 using TestConsoleApp.AdditionService; namespace TestConsoleApp class Program { static void Main(string[] args) { AdditionServiceClient client = new AdditionServiceClient(); Complex c1 = new Complex(), c2 = new Complex(); c1.real = 3; c1.imag = 5; c2.real = 1; c2.imag = 7; Complex result = client.Add(c1, c2); } } } 

注意这是多么简单。 基本上,实例化客户端代理AdditionServiceClient 。 然后创建两个Complex对象。 最后,调用客户端代理上的Add()方法,并返回Complex结果。

幕后发生的事情是客户端代理的Add()方法实际上是将两个Complex对象传递给Windows服务中托管的AdditionService WCF服务。 AdditionService执行添加,然后返回结果。 所有这些都发生在命名管道上,但请注意,这里根本没有命名管道专用代码! WCF已经抽象出了IAdditionService接口定义的编程模型背后的所有复杂性。

我知道这是要消化的大量信息,但我希望WCF的强大和易用性是显而易见的。 当然,此示例仅触及WCF中可用的所有内容的一小部分。

但最后,WCF应该是用于在UI和Windows服务之间进行通信的机制。 有关更多信息,我强烈推荐Juval Lowy为WCF所有内容编写WCF服务的书。 您还可以访问他的网站IDesign.net ,获取免费的WCF代码示例。 有关WCF的更多介绍,请在dnrTV观看此免费video 。 它涵盖了WCF的目的,并通过一些易于理解的示例演示了WCF编程。

最好的办法是在IPC频道上使用.NET远程处理。

虽然设置似乎很复杂,但第二次这很容易。

我建议您首先将一些样本从一个应用程序暴露给另一个应用程序。

我以前没有使用过Message队列,所以我不能对此发表评论。