单击桌面快捷方式时如何从系统托盘恢复单实例应用程序?

时间:2016-10-29 12:02:00

标签: c# wpf

这是我的项目示例。

App.xaml.cs

using BackgroundApplication.Single_Instance_App;
using System.ComponentModel;
using System.Windows;

namespace BackgroundApplication
{    
    public partial class App : Application
    {
        private System.Windows.Forms.NotifyIcon _notifyIcon;
        private bool _isExit;

     protected override void OnStartup(StartupEventArgs e)
        {
            WpfSingleInstance.Make("MyWpfApplication", this);

            base.OnStartup(e);

        }

    }
}

WpfSingleInstance.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace BackgroundApplication.Single_Instance_App
{
  public  class WpfSingleInstance
    {

        internal static void Make(String name, Application app)
        {

            EventWaitHandle eventWaitHandle = null;
            String eventName = Environment.MachineName + "-" + Environment.CurrentDirectory.Replace('\\', '-') + "-" + name;

            bool isFirstInstance = false;

            try
            {
                eventWaitHandle = EventWaitHandle.OpenExisting(eventName);
            }
            catch
            {
                // it's first instance
                isFirstInstance = true;
            }

            if (isFirstInstance)
            {
                eventWaitHandle = new EventWaitHandle(
                    false,
                    EventResetMode.AutoReset,
                    eventName);

                ThreadPool.RegisterWaitForSingleObject(eventWaitHandle, waitOrTimerCallback, app, Timeout.Infinite, false);

                // not need more
                eventWaitHandle.Close();


            }
            else
            {
                eventWaitHandle.Set();

                // For that exit no interceptions
                Environment.Exit(0);


            }
        }


        private static void waitOrTimerCallback(Object state, Boolean timedOut)
        {
            Application app = (Application)state;
            app.Dispatcher.BeginInvoke(new activate(delegate () {
                Application.Current.MainWindow.Activate();
            }), null);
        }


        private delegate void activate();

    }
}

MainWindow.xaml.cs

using Microsoft.Win32;
using System.Windows.Forms;
namespace BackgroundApplication
{   
    public partial class MainWindow : Window
    {    
        public MainWindow()
        {
            InitializeComponent();
        }
        private System.Windows.Forms.NotifyIcon _notifyIcon;

        private void CloseCustomButton_Click(object sender, RoutedEventArgs e)
        {
            this.ShowInTaskbar = false;
            this.Hide();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            _notifyIcon = new System.Windows.Forms.NotifyIcon();
            _notifyIcon.DoubleClick += (s, args) => NormalMainWindow();
            _notifyIcon.Icon = BackgroundApplication.Properties.Resources.MyIcon;
            _notifyIcon.Visible = true;
            _notifyIcon.BalloonTipText = "Background Processing is running";
            _notifyIcon.BalloonTipTitle = "Information";
            _notifyIcon.ShowBalloonTip(50);
            CreateContextMenu();
        }
        private void CreateContextMenu()
        {        
            _notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
            _notifyIcon.ContextMenuStrip.Items.Add("Background Application").Click += (s, e) => NormalMainWindow();
            _notifyIcon.ContextMenuStrip.Items.Add("Maximize").Click += (s, e) => MaxMainWindow();
            _notifyIcon.ContextMenuStrip.Items.Add("Minimize").Click += (s, e) => MinMainWindow();
            _notifyIcon.ContextMenuStrip.Items.Add("Exit").Click += (s, e) => ExitApplication();

        }

        private void NormalMainWindow()
        {
            if (this.IsVisible)
            {
                if (this.WindowState == WindowState.Minimized)
                {
                    this.WindowState = WindowState.Normal;
                    this.ShowInTaskbar = true;
                }
                this.Activate();
            }
            else
            {
                this.Show();
            }
        }
        private void MaxMainWindow()
        {
            if (this.IsVisible)
            {
                if (this.WindowState == WindowState.Normal)
                {
                    this.WindowState = WindowState.Maximized;
                    this.ShowInTaskbar = true;
                }
                this.Activate();
            }
            else
            {
                this.Show();
                this.WindowState = WindowState.Maximized;
                this.Activate();
            }
        }
        private void MinMainWindow()
        {
            if (this.IsVisible)
            {
                if ((this.WindowState == WindowState.Normal) || (this.WindowState == WindowState.Maximized))
                {
                    this.WindowState = WindowState.Minimized;
                    this.ShowInTaskbar = true;
                }
                this.Activate();
            }
            else
            {
                return;
            }
        }
        private void ExitApplication()
        {
            _isExit = true;        
            System.Windows.Application.Current.Shutdown();
            _notifyIcon.Dispose();
            _notifyIcon = null;
        }     
    }
 }

单实例应用程序&托盘系统。

但是如何在单击桌面快捷方式时从系统托盘恢复此应用程序(通过单击“Background Application.exe”)????

2 个答案:

答案 0 :(得分:1)

查看What is the correct way to create a single-instance application?

基本上这个想法是当你启动应用程序的第二个实例并检测到你已经在运行时,你会广播一个窗口消息,你的另一个实例(真实实例)将会捕获然后自己回来到前台。并且您的第二个实例在发送消息后立即退出。

答案 1 :(得分:0)

试试这个:

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);