如何只运行WPF应用程序的一个实例&从任务栏打开最后一个窗口

时间:2015-12-05 05:30:00

标签: c# wpf notifyicon taskbar

如何只运行我的WPF应用程序的一个实例并在任务栏上打开窗口?我知道网上有很多关于这个话题的问题,但是他们都没有明确的答案(或者至少在WPF上有任何答案对我有用)。我在this问题上编写了答案,这是我的代码:

private static Mutex mutex = new Mutex(true, "{1111werqwfwf}");
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;
    }
}

问题是我的MainWindow未打开。另外,我需要打开PointOfSale窗口,这是最小化到任务栏的窗口,这是我的窗口代码(我正在使用NotifyIcon插件):

public partial class PointOfSale : Window
{
    TaskbarIcon tb;

    public PointOfSale()
    {
        InitializeComponent();

        tb = (TaskbarIcon)FindResource("NotifyIcon");
        tb.DoubleClickCommand = new ShowWindowCommand();
        tb.Visibility = System.Windows.Visibility.Visible;
        Utils.Utils.SetTaskBarIcon(tb);
   }
}

当PointOfSale关闭时,我会检查结束事件并隐藏它:

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        Utils.Utils.pointOfSale = this;
        Hide();
        e.Cancel = true;
    }

Utils.Utils.pointOfSale = this;我保存实际窗口的实例,我可以在双击任务栏上的图标时打开它。

有关这方面的信息会有所帮助。

编辑:我认为如果可以杀死应用程序的最后一个实例并且可以创建新的实例,它也可以工作。

1 个答案:

答案 0 :(得分:0)

从最简单的WPF应用程序实现开始,让它作为单例工作 - 然后您可以将该实现重新合并到您正在构建的任何复杂应用程序中。

以下是您可以使用的大纲。这在SO上已经多次被解释了......

在VS中生成样板WPF应用程序,并按如下方式修改App.xaml.cs(并记下代码中的注释,其中提示了一些其他更改)。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;

namespace Singleton
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    /// <remarks>
    /// 1. Change Build Action for App.xaml (right-click, Properties)
    ///     to Page from ApplicaitonDefinition
    /// 2. Go to project settings, and in the Debug tab, uncheck 
    ///     "Enable Visual Studio Hosting Process"
    /// </remarks>
    public partial class App : Application
    {
        [STAThread]
        public static void Main(string[] args)
        {
            bool bNew = true;
            using (Mutex mutex = new Mutex(true, "Singleton-GUID", out bNew)) // Replace string "Singleton_GUID" with one with a real GUID
            {
                if(bNew)
                {
                    new App().Run();
                }
                else
                {
                    Process me = Process.GetCurrentProcess();
                    List<Process> processes = new List<Process>(Process.GetProcesses());

                    var matches = 
                        processes.FindAll((p) => 
                        {
                            return 
                                string.Equals(p.ProcessName, me.ProcessName, StringComparison.InvariantCultureIgnoreCase) && 
                                (p.Id != me.Id);
                        });

                    if (matches.Count == 1)
                    {
                        Process prior = matches[0];
                        if (prior.MainWindowHandle != IntPtr.Zero)
                        {
                            NativeMethods.ShowWindow(prior.MainWindowHandle, NativeMethods.SH_SHOW);
                        }
                    }
                }
            }
        }

        private App()
        {
            InitializeComponent();
        }
    }

    public static class NativeMethods
    {
        [DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        public const int SH_SHOW = 5;
    }
}