I am developing a Windows Service in C# to centrally manage some application connectivity. 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
. 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:
System.Threading.WaitHandleCannotBeOpenedException: No handle of the given name exists.
What am I missing?