3

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?

Community
  • 1
  • 1
juan
  • 80,295
  • 52
  • 162
  • 195
  • Possible duplicate: http://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-application – Fredrik Mörk Jul 17 '09 at 19:58
  • Multiple duplicates: http://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-application http://stackoverflow.com/questions/93989/prevent-multiple-instances-of-a-given-app-in-net http://stackoverflow.com/questions/906100/run-one-instance-from-the-application – Noldorin Jul 17 '09 at 19:58

5 Answers5

6

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
    }
}
Alex McBride
  • 6,881
  • 3
  • 29
  • 30
  • 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. – Yvo Jul 17 '09 at 20:10
  • What would it be for the compact framework? – SwDevMan81 Jul 17 '09 at 21:15
0

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
  • 71,481
  • 13
  • 158
  • 186
0

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

John Fisher
  • 22,355
  • 2
  • 39
  • 64
0

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.

Yvo
  • 18,681
  • 11
  • 71
  • 90
0

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
  • 122,218
  • 32
  • 205
  • 338