Another way to make sure only one instance of your program is running.
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
Comments have been disabled for this content.
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
Douglas Reilly said
I certainly understand the thrill of discovery and learning new ways to do things (even if in the end, a previous method is best).
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);
Tolu said
Works like a charm for me. Thanks!