切换到同一应用程序的其他实例

时间:2011-09-07 20:07:51

标签: c# winforms

如果发生某个事件,我希望我的c#winform应用程序切换到另一个正在运行的实例。

例如,如果我的应用程序只有一个按钮,并且此时正在运行三个实例。现在,如果我

  1. 按第一个实例中的按钮,焦点到第二个实例
  2. 按第二个实例中的按钮,焦点到第三个实例
  3. 按第三个实例中的按钮,焦点到第一个实例
  4. 我该怎么做?

2 个答案:

答案 0 :(得分:7)

如果您知道其他实例的句柄,则应该只调用Windows API: SetForegroundWindow

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

您可以使用 FindWindow API调用来获取其他实例的句柄,例如:

 public static int FindWindow(string windowName)
    {
        int hWnd = FindWindow(null, windowName);

        return hWnd;
    }

您可以在SO中搜索这些api调用以获取更多示例,例如找到这个:

How do I focus a foreign window?

答案 1 :(得分:0)

SetForegroundWindow是一个很好的解决方案。另一种方法是使用命名Semaphores将信号发送到其他应用程序。

最后,您可以查找Inter-Process Communication (IPC)解决方案,该解决方案允许您在进程之间发送消息。

我写了一个简单的.Net XDMessaging库,这让我很容易。使用它,您可以将指令从一个应用程序发送到另一个应用程序,在最新版本中甚至可以通过已下载的对象。这是一个使用频道概念的多播实现。

App1的:

IXDBroadcast broadcast = XDBroadcast.CreateBroadcast(
                                       XDTransportMode.WindowsMessaging);
broadcast.SendToChannel("commands", "focus");

App2的:

IXDListener listener = XDListener.CreateListener(
                                      XDTransportMode.WindowsMessaging);
listener.MessageReceived+=XDMessageHandler(listener_MessageReceived);
listener.RegisterChannel("commands");

 // process the message
private void listener_MessageReceived(object sender, XDMessageEventArgs e)
{
    // e.DataGram.Message is the message
    // e.DataGram.Channel is the channel name
    switch(e.DataGram.Message)
    {
        case "focus":
        // check requires invoke
            this.focus();
            break;
        case "close"
            this.close();
            break;
    }
}