简体   繁体   English

在Windows Service中创建时找不到命名事件

[英]Cannot find named event when created in Windows Service

I am developing a Windows Service in C# to centrally manage some application connectivity. 我正在用C#开发Windows服务,以集中管理某些应用程序连接。 It's a sleeper service in general, which performs some actions when awoken by an external executable. 通常,它是睡眠服务,当外部可执行文件唤醒时执行一些操作。 To this end I'm using named events, specifically the .NET EventWaitHandle . 为此,我使用命名事件,特别是.NET EventWaitHandle My code boils down to, at the service end: 我的代码可以归结为服务端:

        EventWaitHandleSecurity sec = new EventWaitHandleSecurity();
        sec.AddAccessRule(new EventWaitHandleAccessRule(
                  new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                  EventWaitHandleRights.FullControl,
                  AccessControlType.Allow));
        evh = new EventWaitHandle(false, EventResetMode.AutoReset, EVENT_NAME, 
                                  out created, sec);

        Log(created ? "Event created" : "Event already existed?");

As it's an internal application on trusted servers I don't mind that granting 'Full Control' to 'World' in general wouldn't be smart. 因为它是受信任服务器上的内部应用程序,所以我不介意将“完全控制”授予“世界”通常并不明智。

At the client end I have: 在客户端,我有:

EventWaitHandle.TryOpenExisting(EVENT_NAME, EventWaitHandleRights.Modify, out evh)

The code above works perfectly when I run my service in console-based interactive mode. 当我在基于控制台的交互模式下运行服务时,上面的代码可以完美地工作。 The event is found on both ends, the client can set, and the service kicks to work. 该事件在两端都可以找到,客户端可以设置,并且服务可以开始工作。 Everybody's happy. 大家都开心

When installing the service however it doesn't work. 但是,在安装服务时,它不起作用。 The logging still reports that the event was created anew, but the client cannot find the event. 日志记录仍然报告该事件是重新创建的,但是客户端找不到该事件。 As I thought it was security-related I added the World Full Control Allow access rule, but it didn't change anything. 由于我认为这与安全性有关,因此我添加了“世界完全控制允许”访问规则,但没有做任何更改。 I changed the service to run as Local Admin, even as my own user account, but nothing - the client cannot find the event even though logs show the service is happily polling away on it. 我将服务更改为以本地管理员身份运行,甚至以我自己的用户帐户身份运行,但没有执行任何操作-即使日志显示该服务正在愉快地轮询该客户端,客户端也无法找到该事件。 If I change the TryOpenExisting to OpenExisting I get an explicit exception: 如果我将TryOpenExisting更改为TryOpenExistingOpenExisting得到一个明确的异常:

System.Threading.WaitHandleCannotBeOpenedException: No handle of the given name exists.

What am I missing? 我想念什么?

Starting with Windows Vista, services are isolated and run in Session 0 (see Service Changes for Windows Vista ). 从Windows Vista开始,服务是隔离的,并在会话0中运行(请参阅Windows Vista的服务更改 )。 When calling CreateEvent (which EventWaitHandle does), the event object is created in the local namespace by default, also called session namespace. 调用CreateEventEventWaitHandle会这样做 )时,默认情况下在本地名称空间(也称为会话名称空间)中创建事件对象。 An event object created by a service in session 0 with a name in the session namespace is visible in session 0 only. 会话0中的服务在会话名称空间中使用名称创建的事件对象仅在会话0中可见。 It is invisible to applications running in an interactive user session. 它对在交互式用户会话中运行的应用程序不可见。

To create an event object by a service (running in session 0) that can be discovered by application code (running in an interactive user session), you have to create it into the global namespace. 要通过服务(在会话0中运行)可以由应用程序代码发现的事件对象(在交互式用户会话中运行)创建事件对象,必须将其创建到全局名称空间中。 This is done by prefixing the event name with "Global\\" , as documented under CreateEvent . 这是通过在事件名称前面添加“ Global \\”来完成的 ,如CreateEvent所示


A helpful tool to track down kernel object-related bugs is Sysinternal's WinObj . Sysinternal的WinObj是跟踪内核对象相关错误的有用工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM