38

How do I check if my C# Windows application is running ?

I know that I can check the process name but the name can be changed if the exe changes.

Is there any way to have a hash key or something to make my application unique?

4
  • 3
    If you want only one instance have a look at Mutex: stackoverflow.com/questions/819773/… Commented Jan 18, 2011 at 9:05
  • there is a problem with using Mutex that way , plus sometimes i need to restart my application using Application.Restart which would conflict with the mutex pattern. Commented Jan 18, 2011 at 9:10
  • So basically, your question is: "How can I get all of the mutex functionality without actually creating a mutex"? Why not ask how to fix whatever problems you have with using a mutex? Commented Jan 18, 2011 at 10:03
  • @Cody: i guess your right,i should try to fix conflicts with mutex instead. thanks Commented Jan 18, 2011 at 10:12

9 Answers 9

46
public partial class App : System.Windows.Application { public bool IsProcessOpen(string name) { foreach (Process clsProcess in Process.GetProcesses()) { if (clsProcess.ProcessName.Contains(name)) { return true; } } return false; } protected override void OnStartup(StartupEventArgs e) { // Get Reference to the current Process Process thisProc = Process.GetCurrentProcess(); if (IsProcessOpen("name of application.exe") == false) { //System.Windows.MessageBox.Show("Application not open!"); //System.Windows.Application.Current.Shutdown(); } else { // Check how many total processes have the same name as the current one if (Process.GetProcessesByName(thisProc.ProcessName).Length > 1) { // If ther is more than one, than it is already running. System.Windows.MessageBox.Show("Application is already running."); System.Windows.Application.Current.Shutdown(); return; } base.OnStartup(e); } } 
Sign up to request clarification or add additional context in comments.

4 Comments

This is fragile: IsProcessOpen("name of application.exe"). An executable may have changed name between the moment source code is written and the moment it is run on user's machine. Mutex don't have this problem and don't make assumption about how application is run.
Is there any way to "switch to" or "bring the process to front" if another instance of application is running ?
Enumerate windows of the process and find the foreground one: EnumWindows. Then bring this window to the front.
@abramlimpin App cannot derive sealed type Application
25

The recommended way is to use a Mutex. You can check out a sample here : http://www.codeproject.com/KB/cs/singleinstance.aspx

In specific the code:

 /// /// check if given exe alread running or not /// /// returns true if already running private static bool IsAlreadyRunning() { string strLoc = Assembly.GetExecutingAssembly().Location; FileSystemInfo fileInfo = new FileInfo(strLoc); string sExeName = fileInfo.Name; bool bCreatedNew; Mutex mutex = new Mutex(true, "Global\\"+sExeName, out bCreatedNew); if (bCreatedNew) mutex.ReleaseMutex(); return !bCreatedNew; }

3 Comments

This will work if the checking application is the same as the running application.
It will work with any application if you use a GUID instead of sExeName.
In which function of my C# application this should be placed?
1

For my WPF application i've defined global app id and use semaphore to handle it.

public partial class App : Application { private const string AppId = "c1d3cdb1-51ad-4c3a-bdb2-686f7dd10155"; //Passing name associates this sempahore system wide with this name private readonly Semaphore instancesAllowed = new Semaphore(1, 1, AppId); private bool WasRunning { set; get; } private void OnExit(object sender, ExitEventArgs e) { //Decrement the count if app was running if (this.WasRunning) { this.instancesAllowed.Release(); } } private void OnStartup(object sender, StartupEventArgs e) { //See if application is already running on the system if (this.instancesAllowed.WaitOne(1000)) { new MainWindow().Show(); this.WasRunning = true; return; } //Display MessageBox.Show("An instance is already running"); //Exit out otherwise this.Shutdown(); } } 

Comments

0

Checkout: What is a good pattern for using a Global Mutex in C#?

// unique id for global mutex - Global prefix means it is global to the machine const string mutex_id = "Global\\{B1E7934A-F688-417f-8FCB-65C3985E9E27}"; static void Main(string[] args) { using (var mutex = new Mutex(false, mutex_id)) { // edited by Jeremy Wiebe to add example of setting up security for multi-user usage // edited by 'Marc' to work also on localized systems (don't use just "Everyone") var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); securitySettings.AddAccessRule(allowEveryoneRule); mutex.SetAccessControl(securitySettings); //edited by acidzombie24 var hasHandle = false; try { try { // note, you may want to time out here instead of waiting forever //edited by acidzombie24 //mutex.WaitOne(Timeout.Infinite, false); hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) return;//another instance exist } catch (AbandonedMutexException) { // Log the fact the mutex was abandoned in another process, it will still get aquired } // Perform your work here. } finally { //edit by acidzombie24, added if statemnet if (hasHandle) mutex.ReleaseMutex(); } } } 

3 Comments

-1: as the OP says, he knows he can check the process name, he wants to know what to do if the application name is changed
@djeeg: Did we read the same question? Can you pin point where op says, he wants to know what to do if the application name is changed?
line number 2: "i know i can check the process name but the name can be changed if the exe changed."
0

you need a way to say that "i am running" from the app,

1) open a WCF ping service 2) write to registry/file on startup and delete on shutdown 3) create a Mutex

... i prefer the WCF part because you may not clean up file/registry correctly and Mutex seems to have its own issues

Comments

0

Mutex and Semaphore didn't work in my case (I tried them as suggested, but it didn't do the trick in the application I developed). The answer abramlimpin provided worked for me, after I made a slight modification.

This is how I got it working finally. First, I created some helper functions:

public static class Ext { private static string AssemblyFileName(this Assembly myAssembly) { string strLoc = myAssembly.Location; FileSystemInfo fileInfo = new FileInfo(strLoc); string sExeName = fileInfo.Name; return sExeName; } private static int HowManyTimesIsProcessRunning(string name) { int count = 0; name = name.ToLowerInvariant().Trim().Replace(".exe", ""); foreach (Process clsProcess in Process.GetProcesses()) { var processName = clsProcess.ProcessName.ToLowerInvariant().Trim(); // System.Diagnostics.Debug.WriteLine(processName); if (processName.Contains(name)) { count++; }; }; return count; } public static int HowManyTimesIsAssemblyRunning(this Assembly myAssembly) { var fileName = AssemblyFileName(myAssembly); return HowManyTimesIsProcessRunning(fileName); } } 

Then, I added the following to the main method:

[STAThread] static void Main() { const string appName = "Name of your app"; // Check number of instances running: // If more than 1 instance, cancel this one. // Additionally, if it is the 2nd invocation, show a message and exit. var numberOfAppInstances = Assembly.GetExecutingAssembly().HowManyTimesIsAssemblyRunning(); if (numberOfAppInstances == 2) { MessageBox.Show("The application is already running! +"\nClick OK to close this dialog, then switch to the application by using WIN + TAB keys.", appName, MessageBoxButtons.OK, MessageBoxIcon.Warning); }; if (numberOfAppInstances >= 2) { return; }; } 

If you invoke the application a 3rd, 4th ... time, it does not show the warning any more and just exits immediately.

Comments

-1

I really simplistic way I guess would be, for every exe that is running, you could create/open a file on disk in a known location (c:\temp) with a special name "yourapp.lock" and then just count how many of those there are.

A harder way, would be to open up some inter-process communication, or sockets, so with the process list you could interrogate each process to see if it was your application.

1 Comment

not acceptable as i dont think i should request access to write directly to the disk, and that would bring a lot of troubles, but thanks
-1

Enter a guid in your assembly data. Add this guid to the registry. Enter a reg key where the application read it's own name and add the name as value there.

The other task watcher read the reg key and knows the app name.

2 Comments

After app crash reboot will not save you from 'duplicate instance' message. Do not use registry, beware of unclean exit when you forget to remove this value
Well using the registry is one option, same you do when you write a .pid file somewhere on the file system. If the applicaiton crash you need to clean this mess up. Same with the registry, the code need to handle this.
-1

you can simply use varialbles and one file to check for running your program. when open the file contain a value and when program closes changes this value to another one.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.