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

问题描述:

我已经使用C#编写了一个应用程序,该应用程序放置在我们的服务器上。 当有人需要使用它时,应用程序直接从服务器启动,从我们局域网中的任何连接的PC启动。如何检查是否有其他应用程序实例正在运行

有没有简单的方法来检查有多少实例正在运行?或者说,如果还有其他实例,而不是由我开始的实例?


编辑:

这是没有提供后的副本,因为我不希望确保,即只有一个实例运行(如“不要运行超过1在同一时间“应用程序),但只检查,如果不是我以外的其他人正在运行它(在正常情况下,它具有同时在多台PC上)

+1

从“在服务器上运行”或“在服务器上找到文件时在用户计算机上本地运行”开始? – 2013-04-24 18:51:10

+0

这个应用程序在每台PC上本地运行,但可执行文件在服务器上。所以第二个选择。 – 2013-04-24 18:54:37

+0

您可以在服务启动时创建全局命名互斥锁,并在关闭时释放它。然后任何其他进程也可以尝试创建一个具有相同名称的全局互斥体,并查看它是否创建了它。请参阅[此线程](http://*.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567)以打开正确的方式一个互斥体。 – 2013-04-24 19:05:07

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

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处理程序。

有没有简单的方法来知道一个程序的该实例中运行某些机器上相同的二进制文件 - 你的程序需要以某种方式报告“我跑”到一些共享位置在那里比它可以检查是否有其他运行的实例。

如果你只需要检查单个实例有可能打开从同一位置的文件,如果多个实例尝试打开它,它就会失败。

共享位置夫妇选项来计算实例:

  • 更新一些文件,计算机的名称
  • 一些Web服务/网站来ping
  • 共享DB

注意它也意味着如果程序死亡,可能不会在共享位置报告关于此特定实例的完成情况。

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

当你启动应用程序,尝试创建一个名为Semaphore带参数指定的实例所允许的数量。如果WaitOne失败,则表示所有实例都在使用中,因此您退出该应用程序。

这里的示例代码(我的头顶部,粉饰一些微妙的问题,没有错误处理等)

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变化(),这取决于您的应用程序需要。

编辑:哎呀,只是注意到,你实际上不需要这个,但要验证在不同的机器上运行的实例 - 这是很难没有一个机制向服务器报告。