仅允许该程序的一个实例时,从系统托盘恢复窗口

时间:2011-01-04 10:59:26

标签: c# winapi

好吧,标题很长,应该告诉我正面临的问题。

以下是最小化图标托盘时的代码:

void MainFormResize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.ShowInTaskbar = false;
            }
        }

当程序已经打开并且在sys托盘中,并且仍然有人想要打开它的另一个实例时,那么:

    private static void Main(string[] args)
            {
                bool createdNew = true;
                using (Mutex mutex = new Mutex(true, "IPADcommunicator", out createdNew))
                {
                    if (createdNew)
                    {
                        Application.EnableVisualStyles();
                        Application.SetCompatibleTextRenderingDefault(false);
                        Application.Run(new MainForm());
                    }
                    else
                    {
                        Process current = Process.GetCurrentProcess();
                        foreach (Process process in Process.GetProcessesByName(current.ProcessName))
                        {
                            if (process.Id != current.Id)
                            {
                                IntPtr handle = FindWindow(null,"IPADcommunicator");
                                SetForegroundWindow(handle);
                                ShowWindow(handle,5);

                                break;
                            }
                        }
...

但是,它运作不正常。主窗口没有恢复。 我已经google了很多,并没有找到解决这个问题的方法。 提前谢谢!

2 个答案:

答案 0 :(得分:6)

在不可见的窗口上调用SetForegroundWindow()不起作用。还有许多其他可能的失败模式,当你开始传递null时,FindWindow()是一个很糟糕的失败模式。

不要自己发明,.NET已经对单实例应用程序提供了很好的内置支持。您甚至可以在第二个副本启动并通过命令行时收到通知。这就是你想要的,只需恢复窗口而不是破解API。您需要的代码is here

答案 1 :(得分:1)

在查看了包括Hans的链接在内的数十种解决方案之后,我不相信接受的答案的链接会从系统托盘中恢复应用程序。它似乎正在做的就是正确管理单个实例并将参数传递给单个实例。

这里可以在codeplex上找到能够管理单个实例,恢复最小化窗口并恢复系统托盘窗口的更完整的解决方案。 http://www.codeproject.com/KB/cs/SingleInstanceAppMutex.aspx

将其合并到您自己的代码中也非常简单。