Windows服务无法看到命名信号量

Vit*_*aly 7 c# windows-services semaphore

我正在尝试调解一个小的Windows服务,使其在启动期间等待来自另一个进程的信号.当然,我知道这种方法可能(甚至会)有时会导致服务启动超时.事实并非如此.

问题是名为System.Thread.Sempaphore我用于调解目的.使用以下构造在其他地方创建和获取信号量.没有更改GC有它,因为我明确地在给定的行下方执行测试以进行测试.

Boolean newOne;
System.Threading.Semaphore rootSemaphore = 
    new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out newOne);
Run Code Online (Sandbox Code Playgroud)

上面的代码显然效果很好.以下代码在调试模式或控制台应用程序下执行时效果很好:

Boolean createdNew;
System.Threading.Semaphore semaphore = 
    new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew);
if (createdNew) 
    throw new Exception("That's not what we wanted");
Run Code Online (Sandbox Code Playgroud)

作为Windows服务的一部分执行时,完全相同的代码失败:

static class Program
{
    static void Main(string[] args)
    {
        Boolean createdNew;
        System.Threading.Semaphore semaphore = 
            new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew);
        if (createdNew) 
            throw new Exception("That's not what we wanted");

        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new Dummy() };
        ServiceBase.Run(ServicesToRun);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,请寻求帮助.

PS:我一直在尝试使用Mutex,但是还有另外一个问题 - 当所有者调用Mutex时,等待应用程序不会赶上来.ReleaseMutex();

更新:

根据Anurag Ranjhan的反应,我编辑了信号量创建例程,如下所示,这个东西现在工作正常:

Boolean newOne = false;

System.Security.Principal.SecurityIdentifier sid = 
    new System.Security.Principal.SecurityIdentifier(
        System.Security.Principal.WellKnownSidType.WorldSid, 
        null);

System.Security.AccessControl.SemaphoreSecurity sec = 
    new System.Security.AccessControl.SemaphoreSecurity();
sec.AddAccessRule(new System.Security.AccessControl.SemaphoreAccessRule(
    sid,
    System.Security.AccessControl.SemaphoreRights.FullControl,
    System.Security.AccessControl.AccessControlType.Allow));

System.Threading.Semaphore rootSemaphore = 
    new Semaphore(1, 1, "Global\\DummyServiceSemaphore", out newOne, sec);
Run Code Online (Sandbox Code Playgroud)

Raj*_*han 8

尝试使用Global \前缀

System.Threading.Semaphore rootSemaphore = 
new System.Threading.Semaphore(1, 1, "Global\DummyServiceSemaphore", out newOne);
Run Code Online (Sandbox Code Playgroud)

来自MSDN评论部分

如果您在Windows中使用命名的信号量,则您选择的名称受内核命名准则的约束.其中一些指南还包括内核对象命名空间1,它描述了内核对象的上下文.默认情况下,在安装了终端服务的情况下,事件等内核对象仅限于当前的会话.这样做是因为在终端服务中运行的多个会话不会相互产生负面影响.内核对象命名空间描述使用"Local","Global"和"Session"前缀来创建可应用于特定命名空间并与特定范围的进程通信或限制通信的内核对象.