切换到同一应用程序的其他实例
本文关键字:其他 实例 应用程序 | 更新日期: 2023-09-27 18:07:59
我希望我的c# winform应用程序在某个事件发生时切换到另一个运行实例。
例如,如果我有一个应用程序只有一个按钮和三个实例正在运行的时刻。现在如果我
- 第一次按下按钮,聚焦到第二次
- 第二次按下按钮,聚焦到第三次
- 在第三个实例中按下按钮,聚焦到第一个实例
我该怎么做?
如果你知道其他实例的句柄,你应该调用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调用以获得更多示例,例如找到这个:
如何聚焦外部窗口?
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;
}
}