C# 如何从与桌面交互的应用程序与 Windows 服务进行通信?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/84860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 11:24:34  来源:igfitidea点击:

How to communicate with a windows service from an application that interacts with the desktop?

提问by Kris Erickson

With .Net what is the best way to interact with a service (i.e. how do most tray-apps communicate with their servers). It would be preferred if this method would be cross-platform as well (working in Mono, so I guess remoting is out?)

使用 .Net 与服务交互的最佳方式是什么(即大多数托盘应用程序如何与其服务器通信)。如果这种方法也是跨平台的,那将是首选(在 Mono 中工作,所以我猜远程处理已经过时了?)



Edit:

编辑:

Forgot to mention, we still have to support Windows 2000 machines in the field, so WCF and anything above .Net 2.0 won't fly.

忘了说了,我们在现场还是要支持Windows 2000机器,所以WCF和.Net 2.0以上的任何东西都不会飞。

采纳答案by Jason Olson

Be aware that if you are planning to eventually deploy on Windows Vista or Windows Server 2008, many ways that this can be done today will not work. This is because of the introduction of a new security feature called "Session 0 Isolation".

请注意,如果您计划最终在 Windows Vista 或 Windows Server 2008 上进行部署,那么今天可以完成的许多方法将不起作用。这是因为引入了称为“会话 0 隔离”的新安全功能。

Most windows services have been moved to run in Session 0 now in order to properly isolate them from the rest of the system. An extension of this is that the first user to login to the system no longer is placed in Session #0, they are placed in Session 1. And hence, the isolation will break code that does certain types of communication between services and desktop applications.

大多数 Windows 服务现在已移至会话 0 中运行,以便将它们与系统的其余部分正确隔离。对此的扩展是,第一个登录系统的用户不再被放置在会话 #0 中,他们被放置在会话 1 中。因此,隔离将破坏在服务和桌面应用程序之间进行某些类型的通信的代码。

The best way to write code today that will work on Vista and Server 2008 going forward when doing communication between services and applications is to use a proper cross-process API like RPC, Named Pipes, etc. Do not use SendMessage/PostMessage as that will fail under Session 0 Isolation.

在服务和应用程序之间进行通信时,今天编写可在 Vista 和 Server 2008 上运行的代码的最佳方法是使用适当的跨进程 API,如 RPC、命名管道等。 不要使用 SendMessage/PostMessage,因为那样会在会话 0 隔离下失败。

http://www.microsoft.com/whdc/system/vista/services.mspx

http://www.microsoft.com/whdc/system/vista/services.mspx

Now, given your requirements, you are going to be in a bit of a pickle. For the cross-platform concerns, I'm not sure if Remoting would be supported. You may have to drop down and go all the way back to sockets: http://msdn.microsoft.com/en-us/library/system.net.sockets.aspx

现在,根据您的要求,您将陷入困境。对于跨平台问题,我不确定是否支持远程处理。您可能不得不下拉并一直回到套接字:http: //msdn.microsoft.com/en-us/library/system.net.sockets.aspx

回答by Scott Dorman

Remoting is an option, but it's not cross-platform. Some other ways are to use named pipes, IPC, or kernel events.

远程处理是一种选择,但它不是跨平台的。其他一些方法是使用命名管道、IPC 或内核事件。

回答by Mike Dimmick

Funnily enough I was going to suggest Remoting! The Mono 1.0 Release Notes(from archive.org because the original location is missing) mention System.Runtime.Remoting.dll as a supported library and doesn't say anything about known issues.

有趣的是,我打算建议远程处理!该单声道1.0发行说明(从archive.org因为原来的位置丢失)提到对System.Runtime.Remoting.dll作为支持库,不说有关已知问题的东西。

If remoting is out then you probably have to implement your own TCP message framing protocol. Windows doesn't have an equivalent of UNIX-domain sockets for communication on the same machine.

如果远程处理不可用,那么您可能必须实现自己的 TCP 消息帧协议。Windows 没有用于在同一台机器上进行通信的等效 UNIX 域套接字。

回答by gbjbaanb

Most services that have a GUI component are run as a named user, and are allowed access to the desktop. This lets you access it via COM or .NET but only locally (unless you want to get complicated)

大多数具有 GUI 组件的服务都以命名用户身份运行,并允许访问桌面。这使您可以通过 COM 或 .NET 访问它,但只能在本地访问(除非您想变得复杂)

Personally, I open an ordinary old socket on the service - its cross platform, allows multiple clients, allows any app to access it, doesn't rely on Windows security to be opened up for it, and allows your GUI to be written in any language you like (as everything supports sockets).

就我个人而言,我在服务上打开一个普通的旧套接字 - 它的跨平台,允许多个客户端,允许任何应用程序访问它,不依赖于为其打开 Windows 安全性,并允许您的 GUI 以任何方式编写你喜欢的语言(因为一切都支持套接字)。

For a tray app, you'd want a simle protocol to communicate - you might as well use a REST style system to send commands to it, and stream XML (yuk) or a custom data format back.

对于托盘应用程序,您需要一个简单的协议来进行通信 - 您也可以使用 REST 风格的系统向它发送命令,并将 XML (yuk) 或自定义数据格式传回。

回答by Wayne Bloss

Have your service listen to 127.0.0.1 on a predefined port with a plain old TCP stream socket. Connect to that port from your desktop application.

让您的服务在带有普通旧 TCP 流套接字的预定义端口上侦听 127.0.0.1。从您的桌面应用程序连接到该端口。

It's dead simple and it's completely cross platform.

它非常简单,而且完全跨平台。

回答by Jason Hymanson

If this is a tray app, and not a true service, be wary of how you set up your communications if using pipes or TCP/IP. If multiple users are logged into a machine (Citrix, Remote Desktop), and each user launches a tray app "service", then you can run into a situation where you have multiple processes trying to use the same well known port or pipe. Of course this isn't a problem if you don't plan on supporting multiple pipes or if you have a true service as opposed to a tray app that runs in each user shell.

如果这是一个托盘应用程序,而不是真正的服务,请注意在使用管道或 TCP/IP 时如何设置通信。如果多个用户登录到一台机器(Citrix、远程桌面),并且每个用户启动一个托盘应用程序“服务”,那么您可能会遇到多个进程尝试使用同一个众所周知的端口或管道的情况。当然,如果您不打算支持多个管道,或者如果您有一个真正的服务而不是在每个用户 shell 中运行的托盘应用程序,这不是问题。

回答by skolima

Did any one of you actually try remoting with Mono? It works just fine. You might bump into some corner cases, but this is highly unlikely. Just test your application for cross-platform (MS.Net <-> Mono) remoting from time to time to catch any possible glitches. And start with a recent Mono, 2.4.2 is current.

你们中有人真的尝试过使用 Mono 进行远程处理吗?它工作得很好。您可能会遇到一些极端情况,但这极不可能。只需不时测试您的应用程序的跨平台 (MS.Net <-> Mono) 远程处理即可发现任何可能的故障。从最近的 Mono 开始,2.4.2 是最新的。