c#显示进程的隐藏窗口

c#显示进程的隐藏窗口,c#,process,window,handle,C#,Process,Window,Handle,在我的应用程序中,有一个选项可以隐藏窗口-form.hide(),并在系统托盘中放置一个notify图标,当您单击notify图标时,将显示一个form.show() 如果有人试图运行两个应用程序实例,我希望 A.不运行新实例 B显示第一个实例的窗口 我已经有一个循环来检查是否存在同名的进程。 我可以告诉新的应用程序不要运行(返回应用程序.run之前的program.cs中的(新表单())) 但我还得告诉第一个应用程序显示它的主窗口 我有进程(第一个实例),我可以得到它的句柄,它的id等等 问题

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

如果有人试图运行两个应用程序实例,我希望 A.不运行新实例 B显示第一个实例的窗口

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

但我还得告诉第一个应用程序显示它的主窗口

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

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

对于问题的第一部分,以下是您可以执行的操作。在显示表单之前,将其添加到
Main
。这样做的好处是,您不必按进程名称(可能不是唯一的)进行检查,而是创建了一个具有某种“全局性”的互斥体

关于你问题的第二部分,我建议如下:

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

请记住,在所有进程中执行循环不如使用互斥锁有效。如果你不关心速度,清理代码,你只是想让这个应用程序工作,然后使用这个循环。。对我来说,代码就是诗歌。

只为你重写代码,这会给你你想要的。当打开副本时,它将检查副本并聚焦屏幕

        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();
        }

我对互斥一无所知,但这部分已经完成了,使用循环遍历所有进程,检查是否有同名进程,问题是是否有这样的进程如何显示它的windowEli,您不想按进程名称进行检查,因为我可以将我的程序重命名为与您的程序相同的名称,以防止您的程序启动,或者我可以重命名您程序的第二个文件以启动它两次。如果你对互斥体一无所知,你应该读一读>>Odyodys他不能在'If(!mutexCreated)`中创建第二个互斥体,第一个程序可以在定时器最小化时检查它,或者类似的东西吗?@codecamp已经编辑了我的答案,包括你的建议。。谈谈时机!我尝试了你的另一种方法(从文章中),但它不起作用,我尝试了SetForeGroundIndow(hWnd)和ShowWindow(hWnd,5)在我的情况下,窗口是隐藏的(只有一个notifyicon)Eli Cohen只需使用下面的代码,当你的程序最小化时,程序1将被删除,如果程序已经打开,程序2代码将被启动。我将编辑我的帖子,尝试给出另一个示例。出于安全目的,您不希望按进程名称进行检查,因为我可以将我的可执行文件命名为与您的相同的名称,以防止您的程序启动。或者,有人可以重命名第二个文件来启动您的程序两次。Odyodys使用互斥体提供了一个很好的解决方案。我不在乎是否有人想要故意运行2个实例,我只是不希望他错误地这样做。B我相信,为了显示第一个进程的窗口,我无论如何都必须捕获该进程。@EliCohen不,你不必这样做。检查我的答案。你只需要向主要流程发出“信号”就可以了Eli Cohen我已经更新了我的答案,为你提供了你想要的。看看吧。一个例子对我来说很重要。我尽我最大的努力去理解奥迪写了什么,但为什么是2个winforms?它必须有1个winform的2个实例。因为我没有您的特定程序,我制作了2个单独的程序来测试向2个不同进程发送信号的功能,以演示如何向另一个预先确定的进程发送命令,例如显示窗体。您只需将MessageBox替换为您想做的任何事情。您将在一个程序中使用相同的代码,而不是使用两个表单。使用if检查表单是否已打开,如果已打开,则调用程序2代码。我会尝试更新代码,让你有更清晰的想法。
        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();
        }