【问题标题】:Single instance windows forms application and how to get reference on it?单实例 Windows 窗体应用程序以及如何获取它的参考?
【发布时间】:2009-03-30 12:52:27
【问题描述】:

我有一个 Windows 窗体应用程序,它当时只允许一个实例运行。我已经使用 Mutex 实现了 Singleton。应用程序必须可以从命令行启动(带或不带参数)。应用程序由脚本启动和退出。用户无法对其执行任何操作。

因此,应用程序的目的是简单的“指标”应用程序,它只会为最终用户显示一些视觉和图形信息。最终用户不能用它做任何事情,只是看到它。它是 Windows 窗体应用程序,因为它的视觉和图形外观相对容易实现(您可以将其置于最顶层、无边框等)。

简单地说: 当有人尝试使用 exit 命令行参数运行同一个应用程序时,如何退出当前正在运行的应用程序?

bool quit = (args.Length > 0 && args[0] == "quit") ? true : false;
using (Mutex mutex = new Mutex(false, sExeName))
{
    if (!mutex.WaitOne(0, true)) 
    {
        if (quit)
        {
            // This is the tricky part?
            // How can I get reference to "previous" launced 
            // Windows Forms application and call it's Exit() method.
        }
    } 
    else 
    {
        if (!quit)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

【问题讨论】:

    标签: c# winforms singleton mutex


    【解决方案1】:

    .NET 框架为此提供了一个非常好的通用解决方案。检查此MSDN magazine article 的底部。使用 StartupNextInstanceHandler() 事件处理程序将任意命令传递给正在运行的实例,例如“退出”。

    【解决方案2】:

    这不是把事情复杂化了吗?与其关闭现有实例并启动一个新实例,不如重新激活现有实例?无论哪种方式,下面的代码都应该给你一些关于如何去做的想法......?

    Process thisProcess = Process.GetCurrentProcess();
            Process[] allProcesses = Process.GetProcessesByName(thisProcess.ProcessName);
            Process otherProcess = null;
            foreach (Process p in allProcesses )
            {
                if ((p.Id != thisProcess.Id) && (p.MainModule.FileName == thisProcess.MainModule.FileName))
                {
                    otherProcess = p;
                    break;
                }
            }
    
           if (otherProcess != null)
           {
               //note IntPtr expected by API calls.
               IntPtr hWnd = otherProcess.MainWindowHandle;
               //restore if minimized
               ShowWindow(hWnd ,1);
               //bring to the front
               SetForegroundWindow (hWnd);
           }
            else
            {
                //run your app here
            }
    

    还有一个关于这个here的问题

    【讨论】:

    • 有效!在 'if (otherProccess != null)' 里面我放了:' MessageBox.Show("Application already running!"); thisProcess.Kill(); '。谢谢
    【解决方案3】:

    这是一个你可能想要改进的快速而肮脏的解决方案:

    [STAThread]
    static void Main()
    {
        var me = Process.GetCurrentProcess();
        var otherMe = Process.GetProcessesByName(me.ProcessName).Where(p => p.Id != me.Id).FirstOrDefault();
    
        if (otherMe != null)
        {
            otherMe.Kill();
        }
        else
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
    

    如果应用程序的一个实例已经启动,则该进程被终止;否则应用正常启动。

    【讨论】:

      【解决方案4】:

      我认为最简单的方法如下

      查看链接

      http://codenicely.blogspot.com/2010/04/creating-forms-object.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-30
        • 1970-01-01
        • 1970-01-01
        • 2015-03-02
        • 2018-11-04
        相关资源
        最近更新 更多