2012-03-30 44 views
5

我試圖調解一個小的Windows服務,使它在啓動過程中等待來自另一個進程的信號。當然,我知道這種方法可能(甚至會)會導致服務啓動超時。事實並非如此。Windows服務看不到命名的信號量

問題是我用於調解目的的命名System.Thread.Sempaphore。信號量是使用以下構造創建並獲得的。 GC沒有改變,因爲我爲了測試的目的明確地將執行權限分配到給定行之下。

Boolean newOne; 
System.Threading.Semaphore rootSemaphore = 
    new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out newOne); 

上面的代碼很好,很明顯。在調試模式下或在控制檯應用程序在執行時下面的代碼工作很好:

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"); 

完全相同的代碼時,作爲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); 
    } 
} 

因此,在lookig求助這個。 PS:我一直在嘗試使用Mutex,但是還有另一個問題 - 當所有者調用Mutex.ReleaseMutex()時,等待應用程序沒有趕上。

UPDATE

按阿努拉格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); 

回答

5

Global\前綴嘗試使用

System.Threading.Semaphore rootSemaphore = 
new System.Threading.Semaphore(1, 1, "Global\DummyServiceSemaphore", out newOne); 

來自comment section of MSDN

如果您在Windows中使用的是已命名的信號量,則您選擇的名稱是 ,由內核命名準則管理。這些準則中的一些還包括內核對象命名空間1,其描述了內核對象的上下文 。默認情況下,在安裝終端服務時, 類似事件的內核對象僅限於當前會話。這是 完成,因此在終端服務中運行的多個會話不會對 產生不利影響。內核對象命名空間使用「本地」, 「全局」和「會話\」前綴來描述,以創建內核對象,可以將 應用於特定命名空間,並與特定範圍的進程通信或限制 通信。

+0

謝謝!這解決了這個問題。 – Vitaly 2012-04-02 08:01:25

+1

我最近遇到了同樣的問題,即使使用「全局」前綴,我仍然必須顯式指定SemaphoreSecurity對象,如上面問題更新中所示,以使其在Windows服務中工作。不過,這個工作! – mthierba 2015-01-13 14:14:30