我正在检查我的应用程序是否已经在运行,即使我停止了应用程序,它仍然显示为正在运行。为什么?

10 浏览
0 Comments

我正在检查我的应用程序是否已经在运行,即使我停止了应用程序,它仍然显示为正在运行。为什么?

在Program.cs文件中,我做了以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
System.Windows.Forms;
System.Diagnostics;
DannyGeneral;
namespace mws
{
    static class Program
    {
        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
            try
            {
                if (IsApplicationAlreadyRunning() == true)
                {
                    MessageBox.Show("该应用程序已经在运行中");
                }
                else
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
            }
            catch (Exception err)
            {
                Logger.Write("错误 " + err.ToString());
            }
        }
        static bool IsApplicationAlreadyRunning()
        {
            string proc = Process.GetCurrentProcess().ProcessName;
            Process[] processes = Process.GetProcessesByName(proc);
            if (processes.Length > 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

我使用了一个断点,即使我在Visual Studio中关闭了程序,当我尝试再次运行应用程序时,它返回true,并抛出应用程序已经运行的消息。

在断点中,我看到变量proc包含:My Weather Station.vshost

现在我注意到,只有当我在新的Visual Studio窗口中打开了另一个副本并且应用程序位于另一个硬盘上的其他位置,并且我没有在任何一个Visual Studio窗口中运行应用程序时,才会发生这种情况。

那么,为什么当我在Visual Studio中打开同一个应用程序两次,并且它没有在运行时,它会认为它正在运行?

即使我关闭第二个Visual Studio,我仍然可以在proc中看到My Weather Station.vshost,但这次它返回false。

编辑

我现在发现变量processes在索引0和1中都包含My Weather Station.vshost

如果我关闭第二个Visual Studio,它只包含一个。

问题是,这个My Weather Station.vshost是什么?为什么它被认为是正在运行的应用程序?如何改进这个检查,以便如果我打开多个副本的应用程序,它不会认为应用程序正在运行?

我可以更改这个:

if (processes.Length > 1)

并将其改为> 10,例如

但是我仍然不理解My Weather Station.vshost是什么?为什么它在内存中运行?为什么它被认为是正在运行的应用程序?

0
0 Comments

问题的原因是应用程序正在尝试创建一个"单实例应用程序"。为了解决这个问题,可以使用互斥锁的方式来检查应用程序是否已经在运行中。以下是一个通常被接受的方法,在这个方法中使用了互斥锁来检查应用程序是否已经被持有。

using System;
using System.Threading;
class Program
{
    static void Main()
    {
        Mutex mutex = null;
        const string appName = "MyApp";
        try
        {
            mutex = Mutex.OpenExisting(appName);
        }
        catch (WaitHandleCannotBeOpenedException)
        {
            // 互斥锁不存在,说明应用程序还未启动
        }
        if (mutex == null)
        {
            // 创建互斥锁来标记应用程序正在运行中
            mutex = new Mutex(true, appName);
        }
        else
        {
            // 应用程序已经在运行中,退出当前实例
            Console.WriteLine("Another instance of this application is already running.");
            return;
        }
        // 在这里运行应用程序的主要逻辑
        // 释放互斥锁
        mutex.ReleaseMutex();
    }
}

此外,根据你提供的示例源文件中的引用,似乎你正在使用 Windows Forms,而 Windows Forms 已经内置了此功能。你可以参考下面的链接了解更多详细信息:

[Prevent application launch if already running](https://stackoverflow.com/questions/18477502?lq=1)

希望以上信息对解决你的问题有所帮助。

0