This is my project example.

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

```

**It is exactly ok for single instance application & tray system.**

**But How can I restore this application from system tray when clicking on desktop shortcut (By clicking "Background Application.exe") ????**