Another way to make sure only one instance of your program is running.

Tags: Tech Geek

I just saw Wes' solution, and decided to show another approach to the solution, using WMI.  Here it is...

static void Main() {

     //yank off the appname.exe from the assemblies location

     string[] parts = System.Reflection.Assembly.GetExecutingAssembly().Location.Split("\\".ToCharArray());

     string appName = parts[parts.Length-1];

     //build the wmi query

     string query = "select name from CIM_Process where name = '"+appName+"'";

     //load up the managementobjectsearcher with the query

     System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(query);

     int runcount=0;

     //iterate the collection and (which should only have 1 or 2 instances, and if 3 then its already running

     //1 instaces would be itself, 2 would be self and the other

     foreach (System.Management.ManagementObject item in searcher.Get()) {

          runcount++;

          if(runcount>1) break; //only need to know if there is more then self running

     }

     //if we are running only self (1) then load the form, else exit

     if(runcount==1) {

          Application.Run(new Form1());

     } else {

          System.Windows.Forms.MessageBox.Show("Application already running, exiting.");

          Application.Exit();

    }

}

8 Comments

  • Michael Koziarski said

    I'm not a .NET programmer, but surely there's a better way to handle all this than what you've just shown.

    Surely you could do:

    ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

    if (searcher.Get().Count > 1) {
    // no, already launched
    } else {
    //launch it
    }

    The code's much more readable that way and you save iterating etc.

  • Rob Chartier said

    Tried that but it always throws an exception for me. If I simply add:

    runcount = searcher.Get().Count;

    or even

    System.Management.ManagementObjectCollection col = searcher.Get();
    runcount = col.Count;


    I get the exception:

    An unhandled exception of type 'System.NotSupportedException' occurred in system.management.dll

    Additional information: Specified method is not supported.


    Give it a try and let me know if you can get it to work correctly.

    /rob

  • Douglas Reilly said

    I must say I cannot find a reason why Wes' solution is not better than the one presented here. A little less code, and not relying upon WMI. Am I missing something?

    Just curious (really...).

    Thanks!

  • Wes Haggard said

    I also wanted to make sure that any href-exe(smart clients) could only be ran once as well. In there case the process name shows up as IEExec.exe, I believe and if so then there could be other instances of that running with out your program actually running. Just a potential problem I don't know if it actually is.

    Wes

  • Rob Chartier said

    Douglas: Its an alternative, not a "better" solution. I simply wanted to show another way of doing (almost) the same thing. :)

    Wes: Your probably right, excellent point. Maybe there is some other property from the same wmi class that would allow one to tell between difference instances of IEExec.exe. Unfortunately I cant test it, it crashes on me whenever i try to load any href-exe up.

    I would like to add: I do like Wes's implementation, and unless someone proves to me otherwise (performance, etc..) that MINE is better, if I needed to -I would still use Wes's solution-. I actually dont like the WMI stuff in .NET, never have and unless they fix it, never will.

    /rob

  • Homer said

    You could try with System.Threading.Mutex class: Mutex mtx = new Mutex(false, "SOME_CONSTANT_OF_YOUR_OWN"); bool isAppRunning = !mtx.WaitOne(0, false);

Comments have been disabled for this content.