【问题标题】:Kill other instances if program is running?如果程序正在运行,杀死其他实例?
【发布时间】:2017-03-01 13:26:50
【问题描述】:

我正在尝试这样做,以便如果我的程序的另一个实例正在运行,它应该关闭已经运行的实例并启动新实例。我目前尝试过这个:

[STAThread]
static void Main()
{
    Mutex mutex = new System.Threading.Mutex(false, "supercooluniquemutex");
    try
    {
        if (mutex.WaitOne(0, false))
        {
            // Run the application
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new fMain());
        }
        else
        {
            foreach (Process proc in Process.GetProcesses())
            {
                if (proc.ProcessName.Equals(Process.GetCurrentProcess().ProcessName) && proc.Id != Process.GetCurrentProcess().Id)
                {
                    proc.Kill();
                    break;
                }
            }
            // Run the application
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new fMain());
        }
    }
    finally
    {
        if (mutex != null)
        {
            mutex.Close();
            mutex = null;
        }
    }
}

但由于某种原因,它并没有杀死已经在运行的实例,它只是在大部分时间里杀死自己,有时它根本不做任何事情。

我该怎么做才能让它工作?

编辑:我知道通常的做法是显示应用程序已经在运行的消息,但在这个应用程序中,它杀死旧进程而不是显示消息是至关重要的。

【问题讨论】:

  • 那么您是说当您在调试时遇到proc.Kill(); 语句,它不会导致进程被杀死?
  • 我认为你只是不想启动新实例,而不是从已经执行的实例下拉地毯。您可以向用户显示一条消息,然后关闭以明确它无法启动....除非您只是不关心其他应用程序实例在做什么(将某些东西保存到商店,提供一些请求,用户做某事等)。还要考虑可能的终端服务器影响......(承载多个同时登录的服务器)。
  • 您确实意识到此的 common 模式是让新实例关闭以支持旧实例(已传输任何参数/将旧实例放在前面) .如果你的用户反其道而行之,用户会感到非常惊讶。
  • 我同意伊戈尔的观点。我宁愿显示错误“进程已在运行”并退出而不是终止现有进程。我也不确定你为什么在那里有一个互斥锁。但是,您当前的代码应该可以工作。让我试试看。
  • 我知道,这是通常的做法,但我的应用程序的意图要求它反转(新的必须杀死旧的)

标签: c# instance mutex kill multiple-instances


【解决方案1】:

首先你需要在杀死前一个进程后再次等待互斥锁。当你说你会得到 AbandonedMutexException。有关please check this link 的详细信息,我假设在该异常之后可以继续。

你可以试试。

Mutex mutex = new System.Threading.Mutex(false, "supercooluniquemutex");
        try
        {
            bool tryAgain = true;
            while (tryAgain)
            {
                bool result = false;
                try
                {
                    result = mutex.WaitOne(0, false);
                }
                catch (AbandonedMutexException ex)
                {
                    // No action required
                    result = true;
                }
                if (result)
                {
                    // Run the application
                    tryAgain = false;
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new fMain());
                }
                else
                {
                    foreach (Process proc in Process.GetProcesses())
                    {
                        if (proc.ProcessName.Equals(Process.GetCurrentProcess().ProcessName) && proc.Id != Process.GetCurrentProcess().Id)
                        {
                            proc.Kill();
                            break;
                        }
                    }
                    // Wait for process to close
                    Thread.Sleep(2000);
                }
            }
        }
        finally
        {
            if (mutex != null)
            {
                mutex.Close();
                mutex = null;
            }
        }

在该示例中,如果我得到 AbandonedMutexException,我将获得 mutext 的所有权并且可以继续。

此外,您使用本地互斥锁,另一个用户可以在另一个终端服务器会话下运行相同的应用程序。 MSDN says

在运行终端服务的服务器上,命名系统互斥锁可以有两个级别的可见性。如果其名称以前缀“Global\”开头,则互斥锁在所有终端服务器会话中可见。如果其名称以前缀“Local\”开头,则互斥锁仅在创建它的终端服务器会话中可见。在这种情况下,具有相同名称的单独互斥锁可以存在于服务器上的每个其他终端服务器会话中。如果您在创建命名互斥锁时未指定前缀,则它采用前缀“Local\”。在终端服务器会话中,名称仅在前缀不同的两个互斥锁是单独的互斥锁,并且对终端服务器会话中的所有进程都是可见的。也就是说,前缀名称“Global\”和“Local\”描述了与终端服务器会话相关的互斥锁名称的范围,而不是与进程相关的范围。

【讨论】:

  • 天哪,这确实有效!但是,还剩下一个问题.. 如果有人重命名可执行文件,它仍然会运行 2 个实例。我该如何反击?不过,非常感谢您到目前为止的回答!
  • 它不会运行,它会尝试查找并杀死旧进程,但找不到同名的进程。 (可能应该有一些限制 - 只检查一次所有进程。)在获得互斥体之前不会显示表单。
猜你喜欢
  • 2012-12-16
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 2023-03-09
  • 2018-12-10
相关资源
最近更新 更多