【问题标题】:How to check if another instance of the application is running [duplicate]如何检查应用程序的另一个实例是否正在运行[重复]
【发布时间】:2011-06-17 21:26:36
【问题描述】:

有人可以说明如何检查程序的另一个实例(例如 test.exe)是否正在运行,如果存在则停止加载应用程序。

【问题讨论】:

标签: c# .net wpf windows


【解决方案1】:

想要一些严肃的代码吗?这里是。

var exists = System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1;

这适用于任何应用程序(任何名称),如果有另一个实例在运行相同应用程序,它将变为true

编辑:要解决您的需求,您可以使用以下任何一种:

if (System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1) return;

从您的 Main 方法退出该方法...或

if (System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1) System.Diagnostics.Process.GetCurrentProcess().Kill();

这将立即终止当前的加载过程。


您需要为.Count()扩展方法添加对System.Core.dll的引用。或者,您可以使用.Length 属性。

【讨论】:

  • 在第二个 sn-p 中返回只会使两个应用程序都死掉,所以现在运行的是 0 而不是 2。
  • @dsp_099 除非它们都在几乎完全相同的时间启动,或者有人以某种方式在无限循环中运行此代码,否则它们不会。你可以在那里清楚地看到.Count > 1
  • 是的,对我来说效果不佳,因为这两个应用程序是通过 msconfig / autostart 执行的,总是双启动
  • @dsp_099 在这种情况下,需要互斥体才能正确检测和处理。有很多关于这个主题的信息。
  • @Vercas 这在终端服务器上不起作用
【解决方案2】:

不确定您所说的“程序”是什么意思,但如果您想将应用程序限制为一个实例,那么您可以使用互斥锁来确保您的应用程序尚未运行。

[STAThread]
static void Main()
{
    Mutex mutex = new System.Threading.Mutex(false, "MyUniqueMutexName");
    try
    {
        if (mutex.WaitOne(0, false))
        {
            // Run the application
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
        else
        {
            MessageBox.Show("An instance of the application is already running.");
        }
    }
    finally
    {
        if (mutex != null)
        {
            mutex.Close();
            mutex = null;
        }
    }
}

【讨论】:

  • 如果你的程序被“硬杀”会怎样?说如果程序崩溃或进程资源管理器被用来以“不友好的方式”杀死应用程序?解决它的唯一方法是重置电脑吗?
  • @TamusJRoyce 不,如果您阅读 MSDN 文档,它清楚地指出,如果 Mutex 被放弃,下一个等待线程将获得它的所有权。
  • 这是正确答案,其他答案对 ex 无效。如果我用另一个名字复制了 exe。
  • 这是唯一有效的答案;接受的答案不是很好
  • “将您的应用程序限制为一个实例”在第二个实例正在运行时会导致错误 - 它还没有走远。仍然是检测另一个实例是否正在运行的好方法。
【解决方案3】:

这里有一些很好的示例应用程序。以下是一种可能的方法。

public static Process RunningInstance() 
{ 
    Process current = Process.GetCurrentProcess(); 
    Process[] processes = Process.GetProcessesByName (current.ProcessName); 

    //Loop through the running processes in with the same name 
    foreach (Process process in processes) 
    { 
        //Ignore the current process 
        if (process.Id != current.Id) 
        { 
            //Make sure that the process is running from the exe file. 
            if (Assembly.GetExecutingAssembly().Location.
                 Replace("/", "\\") == current.MainModule.FileName) 

            {  
                //Return the other process instance.  
                return process; 

            }  
        }  
    } 
    //No other instance was found, return null.  
    return null;  
}


if (MainForm.RunningInstance() != null)
{
    MessageBox.Show("Duplicate Instance");
    //TODO:
    //Your application logic for duplicate 
    //instances would go here.
}

许多其他可能的方式。请参阅替代方案示例。

First one.

Second One.

Third One

编辑 1:刚刚看到您有一个控制台应用程序的评论。 second sample.

对此进行了讨论

【讨论】:

  • 一个 upvote+ 因为这有效,但不幸的是,在我的情况下,我需要在终端服务器上运行它。由于它不是特定于用户的,因此在这种情况下它失败了,因为服务器上一次只有一个用户可以运行它。
【解决方案4】:

Process 静态类有一个 GetProcessesByName() 方法,您可以使用它来搜索正在运行的进程。只需搜索具有相同可执行名称的任何其他进程。

【讨论】:

    【解决方案5】:

    你可以试试这个

    Process[] processes = Process.GetProcessesByName("processname");
    foreach (Process p in processes)
    {
        IntPtr pFoundWindow = p.MainWindowHandle;
        // Do something with the handle...
        //
    }
    

    【讨论】:

    • @R Quijano 这是一种安全/可靠的方式吗?
    • @R Quijano 如果您启动相同的可执行文件,这将不起作用!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多