Ensuring only one instance of your app runs - Ernst Kuschke

   Ernst Kuschke

     Arbitrary thoughts and musings on life, the universe and everything else

Syndication

News

    ernst kuschke (v1.0)

    My Photos

    Microsoft Most Valuable Professional

    Member in good standing

    View Ernst Kuschke's profile on LinkedIn

    Add to Technorati Favorites

Blogs I read

Books I recommend

General Links

Ensuring only one instance of your app runs

A while ago I had the user requirement that one of our WinForm apps “behave like Outlook”, in that only one instance of it ever runs per workstation. If an instance is already running, launching it a second time should bring the existing instance to the foreground.

First I thought that there would be some simple .NET framework functionality to help me accomplish this, but I ended up doing a combination of a mutex and API calling. Thanks to Armand who helped me on this.

The app's entry method tries to acquire a system-unique mutex. If the mutex isn't available, it means that another instance must be running. In this case, the process of this other instance is found, its window changed to a viewable state (it might be minimized), and then brought to the foreground - all with API calls. If the mutex can be acquired, just launch the app. The entry point looks like this:

public static void Main()
{
    bool firstInstance;
    Mutex mut = new Mutex(true, strSystemMutex, firstInstance);
    if (firstInstance) { 
        try
            Application.EnableVisualStyles();
            Application.Run(new frmLogin()); 
        }
catch (Exception ex) {
            ExceptionManager.Publish(ex);
        } finally {
            mut.ReleaseMutex();
        }
    } else {
        try {
            Process[] processes = Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName);
            Process proc;
            foreach (Process proc in processes) {
                if (!proc.Id == Process.GetCurrentProcess.Id) {
                    WindowsHelper.ActivateWindowByHandle(UInt32.Parse(proc.MainWindowHandle.ToString()));
                    System.Environment.Exit(0);
                }
            }
        } catch (Exception ex) {
            ExceptionManager.Publish(ex);
        } 
    }
}

The WindowsHelper class I use can be found over here (it does the unmanaged API calls via a managed wrapper)

[UPDATE: Fixed the broken link to the WindowsHelper class ;o)]

Published Tuesday, July 20, 2004 10:52 AM by Ernst Kuschke

Comments

# re: Ensuring only one instance of your app runs@ Wednesday, July 21, 2004 4:27 PM

Can't you do it a little simpler - like this:

static void Main()
{
string proc = Process.GetCurrentProcess().ProcessName;
Process[] procs = Process.GetProcessesByName(proc);
if (procs.Length > 1)
{
MessageBox.Show("An instance of Your App is already running.", "Your App",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
Application.Run(new Form1());
}

by Craig

# re: Ensuring only one instance of your app runs@ Thursday, July 22, 2004 8:39 AM

Ah, of course, I *could* do it that way, but then the other instance wouldn't be brought to the foreground through the call to:
WindowsHelper.ActivateWindowByHandle...

# re: Ensuring only one instance of your app runs@ Thursday, July 22, 2004 3:16 PM

Just one thing, stay away from using "Application.EnableVisualStyles(); " in .NET 1.1.
Rather use manifest files as there are currently bugs in the implementation on Application.EnableVisualStyles(); .

# re: Ensuring only one instance of your app runs@ Tuesday, July 27, 2004 3:08 PM

Hmmm ... good point. My mistake, sorry.

by Craig

# re: Ensuring only one instance of your app runs@ Wednesday, July 28, 2004 9:46 AM

Although I should optimize the code as in your post - I don't need to call Process.GetCurrentProcess().Id on each iteration, so:

string ThisProcName = Process.GetCurrentProcess().Id;
foreach (Process proc in processes) {
if (!proc.Id == ThisProcName) {
WindowsHelper.ActivateWindowByHandle(UInt32.Parse(proc.MainWindowHandle.ToString()));
System.Environment.Exit(0);
}
}

# WindowsHelper@ Sunday, August 22, 2004 8:45 PM

# re: Ensuring only one instance of your app runs@ Monday, August 23, 2004 8:34 PM

Hi Ernst:

This is a very nice example, thank you. One area to watch, however, is in a terminal services environment. The Process class can give you back a process from another login session, so the window in the local session might not get focus.

# re: The Misunderstood Mutex@ Tuesday, August 24, 2004 9:25 AM

# @ Sunday, August 29, 2004 7:08 PM

by TrackBack

# re: Ensuring only one instance of your app runs@ Tuesday, March 22, 2005 4:23 PM

Some remarks.

(1) I checked the code on .NET framework 1.1 and it has some errors:
* The firstInstance must be prefixed with out when passed to the Mutex constructor.
* The declaration of 'Process proc;' just above the foreach loop is needless and cause error because it's declared again in the loop.

(2) The concept of this code will not work. The Mutex is a local variable that the GC will collect although it in the Main() method that leans during the entire life time of the application.
The Mutex should wrapped in a class that must be a live during the entire running of the application (like singleton class).

by Sharon

# re: Ensuring only one instance of your app runs@ Tuesday, March 22, 2005 4:55 PM

Sharon,

I do indeed have this code working in a production environment.

(1) That parameter is indeed <out> - thanks!
The rest was done in a comment [1]
(2) The mutex is *not* a variable that will be collected by the GC. It's a Win32 concept, and in this specific case, system-wide, iow. visible to other AppDomains.
A singleton would not work for exactly this reason - it will not be visible to other processes / appdomains.

[1] - http://dotnet.org.za/ernst/archive/2004/07/20/2887.aspx#3028

# re: Ensuring only one instance of your app runs@ Tuesday, March 22, 2005 5:08 PM

I must say that in .NET it for sure does not work, at least not all the time.

I think you should take alook at:
(1) http://msdn.microsoft.com/newsgroups/managed/default.aspx?dg=microsoft.public.dotnet.languages.csharp&mid=44ee3934-33a3-4bef-8ca3-38b262252ff6
(2) http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

by Sharon

# re: Ensuring only one instance of your app runs@ Wednesday, March 23, 2005 8:35 AM

Sharon, what problem do you get? Does it just not work???

# re: Ensuring only one instance of your app runs@ Wednesday, March 23, 2005 8:53 AM

Sharon,

I posted a solution and explanation over here: http://msdn.microsoft.com/newsgroups/managed/default.aspx?dg=microsoft.public.dotnet.languages.csharp&mid=44ee3934-33a3-4bef-8ca3-38b262252ff6

# Forcing just one instance of an Application to execute at a time &laquo; Akbar&#8217;s Weblog@ Monday, July 14, 2008 6:57 PM

Pingback from  Forcing just one instance of an Application to execute at a time &laquo; Akbar&#8217;s Weblog

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: