我想显示另一个应用程序的窗口,如果它被隐藏了。更具体地说,如果用户尝试再次启动它,我想显示已经启动的应用程序的主窗口。我已经实现了对重复应用程序启动的监控。试图像here那样做,但失败了。考虑使用远程处理,但我知道这不是最好的做法,尽管在这种情况下我不需要为Windows API而烦恼。
答案 0 :(得分:0)
这是一种非常糟糕的做事方式。我建议使用命名管道(System.IO.Pipes
)来表示应用程序的第一个副本。收到信号后,第一个副本将激活窗口本身。并且不用担心任何权限。
答案 1 :(得分:0)
另一种非常简单的方法是使用Windows事件,在.NET中表示为System.Threading.EventWaitHandle
类。
在应用程序中创建一个线程,它所做的就是等待命名事件。当事件发出信号时,该线程将使用Form.BeginInvoke
显示主窗口,然后返回等待事件。
从应用程序的新实例中,您只需要发出事件信号。
这比使用管道要少一些工作。
请注意,无论采用哪种方式(使用管道,窗口或事件),您都必须处理权限。
例如,如果启用了UAC,并且现有应用程序实例以admin身份运行,则新实例可能无法向其发送显示该窗口的消息,除非您确保设置了适当的权限(例如,管道或事件,无论你的方法是什么)提前。
答案 2 :(得分:0)
我已经使用远程处理实现了它,但是当我有更多的空闲时间时,我会考虑其他方法。我是这样做的: 在表单类中我们有:
public Main()
{
InitializeComponent();
this.ShowFromFormShower = new FormShower.ShowFromFormShowerDelegate(this.ShowFromFormShower1);
FormShower.Register(this);
}
private void ShowFromFormShower1()
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.BringToFront();
}
public PKW.FormShower.ShowFromFormShowerDelegate ShowFromFormShower;
还需要创建远程类:
public class FormShower : MarshalByRefObject
{
/// <summary>
/// For remote calls.
/// </summary>
public void Show()
{
if (FormShower.m == null)
throw new ApplicationException("Could not use remoting to show Main form because the reference is not set in the FormShower class.");
else
FormShower.m.Invoke(FormShower.m.ShowFromFormShower);
}
private const int PortNumber = 12312;
private static Main m = null;
public delegate void ShowFromFormShowerDelegate();
internal static void Register(Main m)
{
if (m == null) throw new ArgumentNullException("m");
FormShower.m = m;
ChannelServices.RegisterChannel(new TcpChannel(FormShower.PortNumber), false);
RemotingConfiguration.RegisterActivatedServiceType(typeof(FormShower));
}
internal static void CallShow()
{
TcpClientChannel c = new TcpClientChannel();
ChannelServices.RegisterChannel(c, false);
RemotingConfiguration.RegisterActivatedClientType(typeof(FormShower), "tcp://localhost:"+PortNumber.ToString());
FormShower fs = new FormShower();
fs.Show();
}
}
因此,如果用户第二次尝试启动应用程序,则会启动FormShower.CallShow方法。