Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting WinForm application to one process with multiple instances

We have a WinForms application in C# 3.5 (SP 1). We would like to restrict the application to one process in memory with multiple window instances. We are not looking for an MDI approach, but to have separate main form instances without launching multiple application processes.

We are evaluating three approaches:

  1. Windows Messages
  2. COM
  3. WCF

We have the rough details for the first 2 (PInvoke with Windows Messages and overriding WinProc, COM Registry, etc) and they use older technologies.

We discussed the idea of using WCF with named pipes instead and think this may be cleanest and easiest way to accomplish the task at hand.

What is the cleanest, modern way of restricting the application to one process with multiple main form instances?

like image 960
blu Avatar asked Oct 14 '22 15:10

blu


1 Answers

One of the methods I've employed in the past was to make use of a system mutex object. The theory behind it is that the first instance of the application will generate the mutex object and subsequent instances of the application then attempt to open a handle to the predefined mutex and if it exists, then bamo! exit the second and third and fourth .... instance.

public static void CheckSingleInstance()
{
    bool created = false;
    _singleInstance = new Mutex(true, "PredefinedMutexName##1", out created);

    if (!created)
    {
        MessageBox.Show("Another instance of this application is already running. Click OK to switch to that instance.", "Application running", MessageBoxButtons.OK, MessageBoxIcon.Information);

        Process proc = Process.GetCurrentProcess();
        Process[] procs = Process.GetProcessesByName(proc.ProcessName);
        bool exit = false;
        Process process = null;
        foreach (Process p in procs)
        {
            if (p.Id != proc.Id && p.MainModule.FileName == proc.MainModule.FileName)
            {
                // ShowWindow(p.MainWindowHandle, 1/*SW_SHOWNORMAL*/);
                process = p;
                exit = true;
            }
        }
        if (exit)
        {
            Application.Exit();

            if (process != null)
                NativeMethods.SetForegroundWindow(process.MainWindowHandle);

            return;
        }
    }
}
like image 100
Mike J Avatar answered Oct 20 '22 00:10

Mike J