I have a console application in C# in which I run various arcane automation tasks. I am well aware that this should really be a Windows Service since it nee
// Allow running single instance
string processName = Process.GetCurrentProcess().ProcessName;
Process[] instances = Process.GetProcessesByName(processName);
if (instances.Length > 1)
{
MessageBox.Show("Application already Running", "Error 1001 - Application Running");
return;
}
Gracefully exit application with messagebox as shown above if application is already running
Jeroen already answered this, but the best way by far is to use a Mutex... not by Process. Here's a fuller answer with code.
Mutex mutex;
try
{
mutex = Mutex.OpenExisting("SINGLEINSTANCE");
if (mutex!= null)
{
Console.WriteLine("Error : Only 1 instance of this application can run at a time");
Application.Exit();
}
}
catch (WaitHandleCannotBeOpenedException ex)
{
mutex = new Mutex(true, "SINGLEINSTANCE");
}
Also bear in mind that you need to run your Application in some sort of Try{} Finally{} block. Otherwise if you're application crashes without releasing the Mutex then you may not be able to restart it again later.
You can search process names of existing system process. For example code, see this blog post.
You can also used a named system Mutex to see if your process is already running.
Here is some sample code. This tends to be more reliable in my experience, and is much simpler, more understandable code.
This article talks about it: Prevent a second process instance from running. It's in VB.net but you can convert it.
The problem in writing a generic function that checks whether the current application is already running comes from the fact that the ProcessName property of the Process object seems to be limited to 15 characters, so longer process names are truncated.
A safer way to retrieve a process name is to get the filename of its main module and dropping the extension. The following reusable routine uses this approach:
Function AppIsAlreadyRunning() As Boolean
' get the filename of the main module
Dim moduleName As String = Process.GetCurrentProcess.MainModule.ModuleName
' discard the extension to get the process name
Dim procName As String = System.IO.Path.GetFileNameWithoutExtension(moduleName)
' return true if there are 2 or more processes with that name
If Process.GetProcessesByName(procName).Length > 1 Then
Return True
End If
End Function