如何检查是否有其他应用程序实例在运行

我在C#中编写了一个应用程序,它放在我们的服务器上。 当有人需要使用它时,应用程序直接从服务器启动,从LAN中任何连接的PC启动。

有没有简单的方法来检查运行的实例数量? 或者更确切地说,如果有任何其他实例而不是我开始的实例?


编辑:

这不是提供的post的重复,因为我不想确保只有一个实例在运行(如“不要同时运行多于1个应用程序”)但只是检查,如果我以外的人正在运行它(在正常情况下,它必须在多台PC上同时工作)

没有简单的方法可以知道程序的实例在同一个二进制文件的某台机器上运行 – 你的程序需要以某种方式报告“我正在运行”到某个共享位置,而不是检查是否有其他实例正在运行。

如果您只需要检查单个实例,则可以从同一位置打开文件,如果多个实例尝试打开它,它将失败。

耦合共享位置选项以计算实例:

  • 用机器名更新一些文件
  • 一些web服务/站点ping
  • 共享数据库

请注意,这也意味着如果程序死亡,共享位置中可能没有关于此特定实例完成的报告。

有几种方法可以做,例如,使用套接字,数据库的东西。 最简单的方法(但不安全)可能是使用文件来记录实例的数量,您可能想要改进它。

void WriteToFile(int x, int millisecondsTimeout) { for(; ; Thread.Sleep(millisecondsTimeout)) try { using(var file=File.Open("instances.bin", FileMode.OpenOrCreate)) { var bytes=new byte[sizeof(int)]; file.Read(bytes, 0, sizeof(int)); var instances=x+BitConverter.ToInt32(bytes, 0); if(instances>-1) file.Write(BitConverter.GetBytes(instances), 0, sizeof(int)); break; } } catch(IOException ex) { } } void Increment() { // invoke on program starts WriteToFile(1, 1000); } void Decrement() { // invoke on program exits WriteToFile(-1, 1000); } 

请注意,文件"instances.bin"应该是位于服务器上的文件。

一旦程序意外终止,您可能还想编写AppDomain.CurrentDomain.UnhandledException处理程序。

通常,要仅允许应用程序的N个并发实例,您可以使用命名信号量,因为它们在整个系统中可见。

启动应用程序时,尝试使用指定允许的实例数的参数创建命名信号量 。 如果WaitOne失败,这意味着所有实例都在使用中,因此您退出应用程序。

这是示例代码(我的头脑,掩盖了一些微妙的问题,没有error handling等)

  const int MAX_INSTANCES = 2; // set desired number of concurrent instances var s = new Semaphore(MAX_INSTANCES, MAX_INSTANCES, "unique_name_of_semaphore"); if (s.WaitOne(0)) // zero timeout - exit immediately if exhausted { // good, we're in, run the app Application.Run(new Form()); // run the app - a winforms example s.Release(); // release the semaphore } else { // oops, exhausted: MessageBox.Show("too many instances running !!"); } 

您还可以使用Semaphore.OpenExisting()的变体,具体取决于您的应用程序需求。

编辑:oops,只是注意到你实际上不需要这个但是要validation在不同机器上运行的实例 – 如果没有向服务器报告的机制,这就更难了。