【问题标题】:How can I check if my program is already running? [duplicate]如何检查我的程序是否已经在运行? [复制]
【发布时间】:2015-02-02 10:03:15
【问题描述】:

我试着这样做:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using DannyGeneral;

namespace mws
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            try
            {
                if (IsApplicationAlreadyRunning() == true)
                {
                    MessageBox.Show("The application is already running");
                }
                else
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
            }
            catch (Exception err)
            {
                Logger.Write("error " + 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 中加载我的项目然后运行我的程序时,它会检测我的项目的 vshost.exe 文件,例如:My project.vshost

并且我希望它仅在我运行程序时才检测我的程序是否在运行,例如只有当它找到 .exe 时:我的 project.exe 而不是 vshost。

【问题讨论】:

  • 您可以尝试禁用Visual Studio托管进程,在这种情况下,该进程不会命名为vshost
  • 那么你真正想要的是检测你是否在“vshost”中运行?

标签: c# .net winforms


【解决方案1】:

看看使用互斥锁。

static class Program {
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    [STAThread]
    static void Main() {
        if(mutex.WaitOne(TimeSpan.Zero, true)) {
            try
            {
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new Form1());
            }
            finally
            {
             mutex.ReleaseMutex();
            }
        } else {
            MessageBox.Show("only one instance at a time");
        }
    }
}

如果我们的应用程序正在运行,WaitOne 将返回 false,您将收到一个消息框。

正如@Damien_The_Unbeliever 正确指出的那样,您应该为您编写的每个应用程序更改互斥锁的 Guid!

来源:http://sanity-free.org/143/csharp_dotnet_single_instance_application.html

【讨论】:

  • 可能值得在 GUID 上方和下方添加一个令人讨厌的注释,指出应该为您放置此代码的每个应用程序生成一个新注释。否则,一旦有几个人将此代码 C&Ped 到他们的项目而不考虑它,你有一个类程序,在任何时候只有一个实例可以运行。
  • @Damien_The_Unbeliever 或者更好地使用应用程序名称本身。 Mutex mutex = new Mutex(true, Assembly.GetEntryAssembly().GetName().Name, out createdNew);
  • @Siriam - 如果多个人决定对不同的程序使用相同的名称,这可能会有自己的问题。 GUID 想法本身并不是一个坏想法,因为只有在以下情况下才会发生冲突需要编辑。
  • 它在编辑器上不工作,但在编译模式下工作得很好。
【解决方案2】:

你能试试下面的sn-p吗?

private static void Main(string[] args)
    {

        if (IsApplicationAlreadyRunning())
        {
            Console.Write("The application is already running");
        }
        else
        {
            Console.Write("The application is not running");
        }
        Console.Read();
    }

     static bool IsApplicationAlreadyRunning()
    {
        return Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly().FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) > 1;
    }

【讨论】:

  • 这远没有互斥锁那么可靠。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多