How should I write an app that will allow only one instance?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

How does one write an app (Console or WinForms) that will detect if an
instance of it is already running and not allow itself to run if so?
 
In VB 6, there was a PrevInstance property that detected if an instance was
already running. I haven't done it in .NET, though, but if you search on
PrevInstance you'll get some sample code for a .NET version.
 
You could also create a MUTEX using the application name. If it already
exits you no the application is running.

static void Main(string[] Args)
{
bool cnew=false;
System.Threading.Mutex mt= new
System.Threading.Mutex(true,"APPLICATION_NAME",out cnew);
if(!cnew)
{
mt.Close();
//exit app already running.
return;
}
//Run app
//Close/release mutex when app closes.
mt.Close();
}



Bill
 
That works just fine, but I'd like to pass along a word of warning to anyone
else unfamiliar with this...

In Bill's sample he calls mt.Close() after using the mutex. I skipped this
part. The app worked as expected in debug mode, but failed in release mode. I
expect that the mutex was optimized away after I checked the boolean, as it
wasn't being used anymore. The result being that the mutex no longer existed
when another instance of my app started.

By adding the call to Close() or ReleaseMutex(), you ensure that the
resource will live long enough to be useful.
 
I also meant to mention, that for the name of the mutex I tried to use:

System.Windows.Forms.Application.ExecutablePath

but received an error:

Unhandled Exception: System.ApplicationException: The system cannot find the
path specified.

I now use just the name of the executable (via (new System.IO.FileInfo ( xxx
)).Name ) and all is fine.

But why would passing a complete path as the name of the mutex cause an
exception?
 
You could check in all running processes. The scope is limited to your
computer.

Dim Processes() As Process

Dim p As Process

Dim sMyPID As String

' Enumerate all processes, (or get processes by name).

Processes = Process.GetProcesses()

' My Current p.ID

sMyPID = Process.GetCurrentProcess.Id.ToString

For Each p In Processes

If p.ProcessName.ToUpper.StartsWith("YOURAPP") Then

' Check for current process

If p.Id.ToString() = sMyPID Then

' This is your current process (the one you are in now)

Else

' There is another process running

End If



End If

Next



Good luck
//Per
 
I don't know whether or not anyone will read this, but I have developed the
class I created to the point now where, in the main routine of a WinForms
application, I can replace the

Application.Run ( new frmX() ) ;

with

ThereCanBeOnlyOne ( typeof(frmX) ) ;

and it takes care of everything.
 
Back
Top