1

我的应用程序中有一个选项可以隐藏窗口 - form.hide(),并在系统托盘中放置一个 notifyicon,当您单击 notifyicon 时会有一个 form.show()。

如果有人会尝试运行该应用程序的两个实例,我想要一个。不运行新实例 b。显示第一个实例的窗口

我已经有一个循环来检查是否存在同名的进程。我可以告诉新应用不要运行(在 program.cs 之前返回Application.run(new form())

但我还必须告诉第一个应用程序显示其主窗口。

我有(第一个实例的)进程,我可以得到它的句柄它的 id 等。

问题如何使用它的进程显示窗口?

4

2 回答 2

0

对于问题的第一部分,您可以执行以下操作。Main在显示表单之前添加此内容。这样做的好处是您不检查进程名称(可能不是唯一的),而是创建一个以某种方式“全局”的互斥锁。

using (Mutex applicationMutex = new Mutex(true, "SomeRandomTextHere", out mutexCreated))
{
    if (!mutexCreated)
    {
        // Application is already running. Aborting..
        return;
    }

    // Application.Run(..)  goes here, plus other interesting stuff

}

对于您问题的第二部分,我建议以下内容:

  • 创建一个命名事件并将其初始设置为 false。然后在您的应用程序中创建一个监视此事件的工作线程。当它发出信号时,Show从您的主窗体调用您的方法。
  • 另一种方法是搜索主进程的窗口句柄并将其放在前面。这篇文章可以给你一些想法。

请记住,对所有进程执行循环不如使用互斥锁有效。如果你不关心速度,干净的代码,你只是想让这个应用程序工作,那么使用这个循环。对我来说,代码就是诗。

于 2013-06-13T22:27:28.593 回答
0

只为您重写代码,这将为您提供您想要的。打开副本时,它将检查重复项并聚焦屏幕。

        EventWaitHandle ProgramOpen = new EventWaitHandle(false, EventResetMode.ManualReset, "ProgramOpen198472");
        EventWaitHandle FocusProgram = new EventWaitHandle(false, EventResetMode.ManualReset, "FocusMyProgram198472");
        private delegate void focusConfirmed(); Thread FocusCheck; 
        private void focus() { FocusProgram.WaitOne(); this.Invoke(new focusConfirmed(()=>{this.Show(); this.BringToFront();}));}
        private void Form1_Load(object sender, EventArgs e)
        {
            if (ProgramOpen.WaitOne(0))
            {
                FocusProgram.Set();
                this.Close();
            }
            ProgramOpen.Set();
        }

        private void HideButton_Click(object sender, EventArgs e)
        {
            this.Hide();
            FocusProgram.Reset();
            FocusCheck = new Thread(focus);
            FocusCheck.Start();
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FocusProgram.Set();
        }
于 2013-06-13T23:00:22.000 回答