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

本文关键字:恢复 单个 应用程序 实例 系统 单击 桌面 快捷方式 | 更新日期: 2023-09-27 18:15:33

这是我的项目示例。

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;
        }     
    }
 }

对于单实例应用程序是完全可以的&托盘系统。

但是我如何从系统托盘中恢复这个应用程序时,点击桌面快捷方式(通过点击"后台应用程序。exe")????

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

看看创建单实例应用程序的正确方法是什么?

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

试试这个:

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