显示另一种形式

时间:2011-01-11 22:16:26

标签: c# winapi

我想显示另一个应用程序的窗口,如果它被隐藏了。更具体地说,如果用户尝试再次启动它,我想显示已经启动的应用程序的主窗口。我已经实现了对重复应用程序启动的监控。试图像here那样做,但失败了。考虑使用远程处理,但我知道这不是最好的做法,尽管在这种情况下我不需要为Windows API而烦恼。

3 个答案:

答案 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方法。