2012-03-30 51 views
5

Tôi đang cố gắng dàn xếp một dịch vụ cửa sổ nhỏ, làm cho nó chờ tín hiệu từ quá trình khác trong khi khởi động. Để chắc chắn tôi biết rằng cách tiếp cận như vậy có thể (hoặc thậm chí sẽ) đôi khi dẫn đến thời gian chờ khởi động dịch vụ. Đó không phải là trường hợp.Dịch vụ Windows không thể nhìn thấy semaphore có tên

Sự cố có tên System.Thread.Sempaphore tôi sử dụng cho mục đích dàn xếp. Semaphore được tạo ra và mua lại ở một nơi khác bằng cách sử dụng cấu trúc sau đây. Không có thay đổi GC có nó như tôi rõ ràng phá vỡ thực hiện ngay bên dưới dòng nhất định cho mục đích thử nghiệm.

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

Mã trên hoạt động tốt, hiển nhiên. Mã sau hoạt động tốt khi được thực hiện trong chế độ gỡ lỗi hoặc dưới giao diện điều khiển ứng dụng:

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

Chính xác cùng mã thất bại khi được thực hiện như một phần của dịch vụ 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); 
    } 
} 

Vì vậy, lookig để được giúp đỡ về điều này.

PS: Tôi đã cố gắng sử dụng Mutex thay vào đó, tuy nhiên có một vấn đề khác với nó - ứng dụng chờ đợi không bắt kịp khi chủ sở hữu gọi Mutex.ReleaseMutex();

CẬP NHẬT:

Theo Anurag Ranjhan phản ứng tôi đã chỉnh sửa semaphore tạo thói quen như sau và thingy hiện đang làm việc tốt:

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

Trả lời

5

Cố gắng sử dụng với Global\ tiền tố

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

Từ số comment section of MSDN

Nếu bạn đang sử dụng Semaphore có tên trong Windows, tên bạn chọn là được điều chỉnh bởi nguyên tắc đặt tên hạt nhân. Một số nguyên tắc đó cũng là bao gồm các Tên đối tượng Hạt nhân 1, mô tả ngữ cảnh của đối tượng hạt nhân. Theo mặc định, với dịch vụ đầu cuối được cài đặt, đối tượng hạt nhân như sự kiện được giới hạn trong Phiên hiện tại. Đây là được thực hiện vì vậy nhiều phiên chạy trong Dịch vụ đầu cuối sẽ không ảnh hưởng bất lợi đến nhau . Kernel Object Namespaces mô tả sử dụng tiền tố "Local \", "Global \" và "Session \" để tạo các đối tượng hạt nhân có thể áp dụng cho các không gian tên cụ thể và để giao tiếp hoặc giới hạn các thông tin liên lạc .

+0

Cảm ơn bạn! Điều đó giải quyết được vấn đề. – Vitaly

+1

Tôi đã gặp vấn đề tương tự gần đây và thậm chí với tiền tố "Global \", tôi vẫn phải chỉ định rõ ràng đối tượng SemaphoreSecurity như được chỉ ra trong phần cập nhật câu hỏi ở trên để làm cho nó hoạt động bên trong Dịch vụ Windows. Điều đó, tuy nhiên, đã làm công việc! – mthierba

Các vấn đề liên quan