2012-07-14 43 views
4

我正在使用TopShelf來託管我的Windows服務。這是我的設置代碼:強制使用TopShelf服務的單個實例

static void Main(string[] args) 
{ 
    var host = HostFactory.New(x => 
    { 
     x.Service<MyService>(s => 
     { 
      s.ConstructUsing(name => new MyService()); 
      s.WhenStarted(tc => tc.Start()); 
      s.WhenStopped(tc => tc.Stop()); 
     }); 

     x.RunAsLocalSystem(); 
     x.SetDescription(STR_ServiceDescription); 
     x.SetDisplayName(STR_ServiceDisplayName); 
     x.SetServiceName(STR_ServiceName); 
    }); 

    host.Run(); 
} 

我需要確保只有一個應用程序實例可以同時運行。目前,您可以同時將其作爲Windows服務和任意數量的控制檯應用程序啓動。如果應用程序在啓動期間檢測到其他實例,它應該退出

我真的很喜歡mutex的方法,但不知道如何使這與TopShelf合作。

回答

5

這是我工作的。事實證明,這非常簡單 - 互斥體代碼僅在控制檯應用程序的Main方法中存在。之前我用這種方法做了一個錯誤的否定測試,因爲我在互斥體名稱中沒有'全局'前綴。

private static Mutex mutex = new Mutex(true, @"Global\{my-guid-here}"); 

static void Main(string[] args) 
{ 
    if (mutex.WaitOne(TimeSpan.Zero, true)) 
    { 
     try 
     { 
      var host = HostFactory.New(x => 
      { 
       x.Service<MyService>(s => 
       { 
        s.ConstructUsing(name => new MyService()); 
        s.WhenStarted(tc => 
        { 
         tc.Start(); 
        }); 
        s.WhenStopped(tc => tc.Stop()); 
       }); 
       x.RunAsLocalSystem(); 
       x.SetDescription(STR_ServiceDescription); 
       x.SetDisplayName(STR_ServiceDisplayName); 
       x.SetServiceName(STR_ServiceName); 
      }); 

      host.Run(); 
     } 
     finally 
     { 
      mutex.ReleaseMutex(); 
     } 
    } 
    else 
    { 
     // logger.Fatal("Already running MyService application detected! - Application must quit"); 
    } 
} 
0

只需將互斥體代碼添加到tc.Start()並在tc.Stop()中釋放互斥體,同時將互斥體代碼添加到控制檯應用程序的主體中。

1

一個簡單的版本:

static void Main(string[] args) 
{ 
    bool isFirstInstance; 
    using (new Mutex(false, "MUTEX: YOUR_MUTEX_NAME", out isFirstInstance)) 
    { 
     if (!isFirstInstance) 
     { 
      Console.WriteLine("Another instance of the program is already running."); 
      return; 
     } 

     var host = HostFactory.New(x => 
     ... 
     host.Run(); 
    } 
}