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") ????
 
     
     
     
    