2012-07-14 38 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(); 
    } 
}