如何创建单个实例WPF应用程序,在尝试打开另一个实例时还原打开的窗口?

时间:2014-02-14 21:34:11

标签: c# wpf

很抱歉,标题很难理解。我不知道如何说出来。

我有一个应用程序,只允许每个用户会话运行一个实例。 如果用户再次单击以启动应用程序,我希望将该应用程序重点关注。

该窗口可能会显示已折叠的可见性。

如果可见,我知道我可以使用

if (IsIconic(hWnd))
{
    ShowWindowAsync(hWnd, swRestore);
}

SetForegroundWindow(hWnd);

但是如果窗口折叠了,有没有办法让它重新显示?

2 个答案:

答案 0 :(得分:17)

您正在寻找Mutex Class。这很复杂,但幸运的是,Singleton模式已被广泛讨论。有几篇很好的文章,但你可以在Sanity Free Coding网站的C# .NET Single Instance Application页面找到一个很好的实现。从链接页面:

static class Program {
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    [STAThread]
    static void Main() {
        if(mutex.WaitOne(TimeSpan.Zero, true)) {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
            mutex.ReleaseMutex();
        } else {
            MessageBox.Show("only one instance at a time");
        }
    }
}

现在你可能想知道如何在WPF应用程序中使用Main方法,对吧?那么你需要做的一些事情,但并不困难。请参阅Writing a custom Main() method for WPF applications文章,详细解释了这一点。从那篇文章:

  

您基本上需要将应用程序的构建操作从“Application Definition”更改为“Page”,创建一个调用“InitializeComponent”的构造函数,并通过最终调用应用程序的“Run”方法重载之一来编写Main()。 ...也不要忘记从App.xaml中删除“StartupUri”,否则将显示另一个窗口副本(除非您收到错误,因为URI指向不存在的XAML资源)。

因此,通过合并这两个资源,我们可以看到您的App.xaml.cs文件看起来像这样:

public partial class App : Application
{
    private static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    private static MainWindow mainWindow = null;

    App()
    {
        InitializeComponent();
    }

    [STAThread]
    static void Main()
    {
        if(mutex.WaitOne(TimeSpan.Zero, true)) 
        {
            App app = new App();
            mainWindow = new MainWindow();
            app.Run(mainWindow);
            mutex.ReleaseMutex();
        }
        else
        {
            mainWindow.WindowState = WindowState.Normal;
        }
    }
}

答案 1 :(得分:11)

我从App.xaml文件中删除了标记StartupUri

将App.xaml的构建操作从ApplicationDefinition更改为Page(您可以在属性窗口中更改它)。

添加对Microsoft.VisualBasic的引用(命名空间到WindowsFormsApplicationBase)。

在课程App.xaml.cs上,输入以下代码:

public partial class App : Application
{
    App()
    {
        InitializeComponent();
    }

    [STAThread]
    static void Main()
    {
        SingleInstanceManager manager = new SingleInstanceManager();
        manager.Run(new[] {"teste"});
    }
}

public class SingleInstanceManager : WindowsFormsApplicationBase
{
    SingleInstanceApplication app;

    public SingleInstanceManager()
    {
        this.IsSingleInstance = true;
    }

    protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
    {
        // First time app is launched
        app = new SingleInstanceApplication();
        app.Run();
        return false;
    }

    protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
    {
        // Subsequent launches
        base.OnStartupNextInstance(eventArgs);
        app.Activate();
    }
}

public class SingleInstanceApplication : Application
{
    protected override void OnStartup(System.Windows.StartupEventArgs e)
    {
        base.OnStartup(e);

        // Create and show the application's main window
        MainWindow window = new MainWindow();
        window.Show();
    }

    public void Activate()
    {
        // Reactivate application's main window

        this.MainWindow.WindowState = WindowState.Normal;
        this.MainWindow.Activate();
    }
}

我希望它有所帮助:D