|
|
Title | Allow only one instance of a program at one time in Visual Basic .NET |
Description | This example shows how to allow only one instance of a program at one time in Visual Basic .NET. |
Keywords | one instance, instance, previous instance, PrevInstance, VB.NET |
Categories | Software Engineering, Windows, VB.NET |
|
|
Unfortunately Visual Basic .NET doesn't have an easy method for determining whether there is another instance of the application running similar to Visual Basic 6's App.PrevInstance.
One approach I have seen is to use Process.GetCurrentProcess.ProcessName to get the current process's name. Then you use Process.GetProcessesByName to get a list of processes with that name and see if the result contains more than one process. If you get information on more than one process, then there's another instance running.
Unfortunately if you launch an application twice very quickly, they may both be loaded before either calls GetProcessesByName. They both see each other and both conclude that another process is running so, if your program is trying to allow only one instance, they both exit.
The following code does a better job. It uses a similar approach, calling Process.GetCurrentProcess.ProcessName and then Process.GetProcessesByName to get a list of processes with that name. It then loops through the process information comparing each process's start time with the current process's start time. If one of the other processes started before this one, then the function concludes that anotehr instance is running.
|
|
' Return True if another instance
' of this program is already running.
Private Function AlreadyRunning() As Boolean
' Get our process name.
Dim my_proc As Process = Process.GetCurrentProcess
Dim my_name As String = my_proc.ProcessName
' Get information about processes with this name.
Dim procs() As Process = _
Process.GetProcessesByName(my_name)
' If there is only one, it's us.
If procs.Length = 1 Then Return False
' If there is more than one process,
' see if one has a StartTime before ours.
Dim i As Integer
For i = 0 To procs.Length - 1
If procs(i).StartTime < my_proc.StartTime Then _
Return True
Next i
' If we get here, we were first.
Return False
End Function
|
|
When its form loads, the example program uses this code. If function AlreadyRunning returns True, the program tells the user that another instance is running and closes its form.
|
|
' See if another instance is already running.
If AlreadyRunning() Then
MessageBox.Show( _
"Another instance is already running.", _
"Already Running", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
Me.Close()
End If
|
|
Notes
- In one case under Windows 2000 Professional, it seems that the length of the process name was coming back truncated. The program could then not get information about the processes with that name so it didn't even see itself running. To fix this, you can open Solution Explorer, right-click on the program, and change its Assembly Name to something shorter.
- This example is intended to prevent accidents where someone runs the program while another instance is already running. It is not intended to prevent the user from doing this intentionally, for example, to avoid licensing restrictions. The user could rename the executable and run more than one instance. To prevent that, you may want to have the program leave notice of its presence in the Registry so other instances can see it running. Or you could put the program's name in the code and make it check that its process name matches that value so you know the user has not renamed it.
- This program may not run in Vista if permissions prevent it from obtaining process information.
- This is easier in VB 2005. See Allow only one instance of a program at one time in Visual Basic 2005.
|
|
|
|
|
|