Introduction
Sometimes you want your application to run single instance. For example, if
you wrote a server application you probably only want a single instance to run
at a time on the localhost.
This code was developed primarily for a server application running on a
Win2KPro Multi-Processor server. It is intended to make absolutely certain that
only one instance of the application runs at a time regardless of logged on
users. The code detects all processes running in all desktops and all service
executables as well and will not start another process if one is already
running.
There is an easy way to start an application so that it first checks to see
if another application (process) of the same name is already running.
Create a new module as below and:
1) Add the module to your WinForm application project
2) Change the
'MyAppName' occurences as appropriate
3) Change the name of the form to start
the application with [Application.Run(New MainForm)]
4) Change the
StartupObject in the project properties to Main()
That's all it takes. Have fun.
Take a look at the code:
<PRE lang=vb.net>Imports System.Diagnostics
Module SingleInstance
Public Sub Main()
If CheckForDuplicateProcess("MyAppName") Then
Dim dupProcess As String
dupProcess = "There is another instance of MyAppName" & _
" running on this machine." & vbCrLf & _
"This new instance must close." & vbCrLf & vbCrLf & _
"Only 1 instance of MyAppName can exist" & _
" on a machine." & vbCrLf & vbCrLf
MsgBox(dupProcess, MsgBoxStyle.Critical, "Duplicate Process Detected")
Application.Exit()
Else
Application.Run(New MainForm)
End If
End Sub
Private Function CheckForDuplicateProcess(ByVal processName As String) As Boolean
Dim Procs() As Process
Dim proc As Process
Procs = Process.GetProcesses()
Dim count As Integer = 0
For Each proc In Procs
If proc.ProcessName.ToString.Equals(processName) Then
count += 1
End If
Next proc
If count > 1 Then
Return True
Else
Return False
End If
End Function
End Module
The example code has been tested on Win2K Pro and WinXP Pro. In
all cases
it works as expected. No failures of any kind thus far.
Some readers have had a few comments and I have tried
to reply to them below.
ProcessName Truncation By OS
The Process.ProcessName that CheckForDuplicateProcess() uses
to loop thru all running processes is the same as the process name used in Task
Manager. So if you have an exe named me.exe, and if you start two instances of
it, you'll see two processes called 'me' in the task manager. They are not
truncated in the task manager so using ProcessName works as expected.
On Using A Mutex To Obtain A Lock
I did not use the Mutex method because it would not be
reliable on a multi-processor machine. If the original process was running on
processor 1 and a duplicate process was started and attached to processor 2 then
both would get a successful lock and you would have two processes running when
you only want 1. Looping thru all the running processes is the only reliable way
to prevent duplicate processes from starting. The Mutex method has less typing
but is not a good solution for this problem.
On The Question Of Two Instances Starting At The Same
Moment
Two instances starting at exactly the same moment on a single
processor machine is impossible. And very very unlikely on a multi-processor
machine. So unlikely in fact that we need not even worry about it in this
situation.
Senior Software Engineer and Architect at Fractured Thinking. Fractured Thinking markets PostScript tools and components for the .NET developer.