Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single Instance Windows Forms Application with Minimize to Tray

Tags:

c#

.net

winforms

I have a sample WinForm application named "Restoring.exe". While minimizing its window, it will move to system tray and will be hidden in the taskbar. If I click on the notification icon in system tray, the window will come to the front.

public void notifyicon_MouseClick(object sender, System.EventArgs e)
{
    notifyicon.Visible = false;
    Show();
    Activate();
    TopMost = true;
    BringToFront();
    this.WindowState = FormWindowState.Normal;
}

But my actual requirement is, while clicking the application 2nd time, need to restore the application from system tray.

For this, I tried the below code

Program.cs:

static void Main()
{
    if (IsServiceManagerAlreadyRunning())
    {
        Form1 form1 = new Form1();
        form1.Restore();
    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Form1.cs:

public void Restore()
{
    notifyicon.Visible = false;
    Show();
    Activate();
    TopMost = true;
    BringToFront();
    this.WindowState = FormWindowState.Normal;
} 

My actual issue is, if the application is already running, the 'Restore' method is hitting and all the actions listed in that is running and the window is appearing into front. But after completed those actions, the window again goes to the system tray. Not sitting in front.

Could anyone please provide a solution for this?

like image 701
Kathir Subramaniam Avatar asked Oct 08 '15 16:10

Kathir Subramaniam


1 Answers

Making Single Instance

Add a reference to Microsoft.VisualBasic.dll to your project and add this class to your project:

using System;
using Microsoft.VisualBasic.ApplicationServices;
using System.Windows.Forms;

namespace Sample
{
    public class ApplicationController : WindowsFormsApplicationBase
    {
        private Form mainForm;
        public ApplicationController(Form form)
        {
            //We keep a reference to main form 
            //To run and also use it when we need to bring to front
            mainForm = form;
            this.IsSingleInstance = true;
            this.StartupNextInstance += this_StartupNextInstance;
        }

        void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
        {
            //Here we bring application to front
            e.BringToForeground = true;
            mainForm.ShowInTaskbar = true;
            mainForm.WindowState = FormWindowState.Minimized;
            mainForm.Show();
            mainForm.WindowState = FormWindowState.Normal;
        }

        protected override void OnCreateMainForm()
        {
            this.MainForm = mainForm;
        }
    }
}

Then in your Program.cs use that ApplicationController to run the program:

using System;
using System.Windows.Forms;

namespace Sample
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            //create a controller and Pass an instance of your application main form
            var controller =  new Sample.ApplicationController(new YourMainForm());

            //Run application
            controller.Run(Environment.GetCommandLineArgs());
        }
    }
}

Now your application is Single Instance and when you click on your exe file, instead of running another instance, brings the existing instance to front.

Using NotifyIcon

Put a NotifyIcon on your main form and then to hide window when you click minimize button and to show windows when you click on notify icon and you can handle these events:

//When click on notify icon, we bring the form to front
private void notifyIcon_Click(object sender, EventArgs e)
{
    this.ShowInTaskbar = true;
    this.WindowState = FormWindowState.Minimized;
    this.Show();
    this.WindowState = FormWindowState.Normal;
}

//here we check if the user minimized window, we hide the form
private void ApplicationMainForm_Resize(object sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized)
    {
        this.ShowInTaskbar = false;
        this.Hide();
    }
}

//when the form is hidden, we show notify icon and when the form is visible we hide it
private void ApplicationMainForm_VisibleChanged(object sender, EventArgs e)
{
    this.notifyIcon1.Visible = !this.Visible;
}
like image 73
Reza Aghaei Avatar answered Nov 03 '22 23:11

Reza Aghaei