tags:

views:

316

answers:

5

Possible Duplicates:
What is the correct way to create a single instance application?
Prevent multiple instances of a given app in .NET?

Do I check whether another process with the same name exists? (What if the user doesn't have permission to do that?)

Write a file to disk and delete it before exiting? (what about abnormal termination?)

What would be a best practice to do this?

+5  A: 

You can use a Mutex.

bool firstInstance = true;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out firstInstance))
{
    if (firstInstance)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
    else
    {
        // Another instance loaded
    }
}
Fara
The using statement here is important. Always combine the Mutex with: a using statement or GC.KeepAlive(..) or make the Mutex static. You want to prevent the garbage collector from cleaning up your Mutex. Still WindowsFormsApplicationsBase would be my preferred approach.
Zyphrax
What would it be for the compact framework?
SwDevMan81
A: 

You can use the Process class's GetProcessesByName method to look for another running process with the same name, and exit if you find one.

David M
A: 

Generally, a named mutex works best. Here's a link to en example: http://www.iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx

John Fisher
A: 

I depends on the technique you're using. There are quite a few solutions, some more suitable for WPF, some for WinForms:

  • WindowsFormsApplicationsBase (my preferred way)
  • With a Mutex (bit more complex)
  • Checking for a process with the same details (I dislike this one)

More on WindowsFormsApplicationsBase:
http://www.openwinforms.com/single_instance_application.html

More on Mutex and checking a process:
http://www.ravinderweb.com/page/Single-Instance-of-the-Application-using-C-Trick-and-Mutex.aspx

I wouldn't use a File, it's prone to errors and not having File access might even cause Exceptions in your program even though it's not a crucial part of your application.

Zyphrax
A: 

There are several ways to do this, all of which have their advantages and disadvantages, and googling will give you a lot of discussion about it.

The methods you describe have the weaknesses you mention. Also you need to consider how unique you want your instance to be:

  • per WindowStation

  • per machine

I have a class that can be used to force a single instance per WindowStation for Windows Forms applications. Basically it uses P/Invoke to do the following during startup, protecting against a race condition using a Mutex:

  • Define a fixed unique string to identify your app (e.g. a GUID)

  • Obtain a Mutex whose name is derived from your unique string.

  • Call EnumWindows using P/Invoke to enumerate all main windows.

  • In the EnumWindows callback, call GetProp using P/Invoke on each window in turn, passing the window handle and your unique value as arguments. If GetProp detects a window that has your unique key (i.e. another instance of your application), activate it (PostMessage(...SC_RESTORE...), SetForegroundWindow, SetFocus), then exit your new instance.

  • If you enumerate all windows without finding a previous instance, call SetProp using P/Invoke to set your unique value for your application's main form window handle.

  • Release the mutex and continue starting up.

In my use case, this solution is better than simply holding a mutex for the lifetime of the process, because it gives a way to activate the previous instance if the user starts a second instance rather than just exiting. Using GetProp/SetProp gives you a way of identifying your process instance without relying on the process name.

Joe