since 1997 a place for my stuff, and if it helps you then so much the better

 
...
...

Single instances


I used your old ways to force a single instance of VB 3,4, 5 and 6 ... how do you do it in VB.Net?

If there is some single-line Framework method that gets around the age-old silliness, we haven't come across it. But it's not all that hard.

We just ported our old Delphi Mutex logic over and it seemed to do the trick quite nicely. It's done with System.Threading working the Mutex (a Mutex could be thought of as a systemwide flag that goes away when it's creator process ends - they're quite handy little suckers), Process objects to iterate through what's running on the machine, and traditional Win32 API calls for the form visibility manipulation.

Add this module to your WinForms project and make the Sub Main the entry point of the program (in VS project properties). The thing to change is the name of the primary form in your app.

You see that this will not only restrict your app to a single instance, but bring a running instance back to the top of the ZOrder and even bring it back from the minimized state.

  Module main
  
     Private Const MB_TITLE As String = "Smithvoice.com Demo"
  
     Public Const SW_RESTORE = 9
     Public Const HWND_TOPMOST = -1
     Public Const HWND_NOTOPMOST = -2
     Public Const SWP_NOMOVE = &H2
     Public Const SWP_NOSIZE = &H1
  
     Declare Function ShowWindowAsync Lib "user32" (ByVal hwnd As Integer, _
        ByVal nCmdShow As Integer) As Integer
  
     Declare Function SetWindowPos Lib "user32" _
        (ByVal hwnd As Integer, ByVal hWndInsertAfter As Integer, _
        ByVal x As Integer, ByVal y As Integer, _
        ByVal cx As Integer, ByVal cy As Integer, _
        ByVal wFlags As Integer) As Integer
  
     Private m_Mutex As System.Threading.Mutex
  
     Private m_UniqueIdentifier As String = _
        Process.GetCurrentProcess.MainModule.FileName.Replace("\", "_")
  
  
     Sub main()
  
        m_Mutex = New System.Threading.Mutex(False, m_UniqueIdentifier)
        Dim bFound As Boolean = False
        If m_Mutex.WaitOne(1, True) Then
           'first instance
           Dim f As New frmMain
           'start the app by showing the primary form
           f.ShowDialog()
        Else
           'not first instance
           Try
              Dim Procs() As Process = Process.GetProcesses()
              Dim proc As Process
              For Each proc In Procs
  
                 If proc.MainModule.FileName.Replace("\", "_") = m_UniqueIdentifier _
                    And proc.Id <> Process.GetCurrentProcess.Id Then
                       'MsgBox("another")
                       bFound = True
                    Exit For
  
                 End If
  
              Next proc
  
              If bFound Then
                 'start this one
                 Dim temphwnd, x As Integer
                 temphwnd = proc.MainWindowHandle.ToInt32
                 x = ShowWindowAsync(temphwnd, SW_RESTORE)
                 'bring it to the top of the z-order
                 SetWindowPos(temphwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
                 'and release it
                 SetWindowPos(temphwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
              End If
  
              'exceptions from Process.GetProcesses are possbile 
              'on certain hardware running Win2kPro and using Hyperthreading
              'MS is aware of this and while they are not fixing .Net1x
              'they say that the fix will be in .Net2
  
           Catch ex As ArgumentOutOfRangeException
              MsgBox("This program is already running." & vbCrLf & _
              "To maximize performance of your computer only one instance of" & vbCrLf & _
              "this program can run at a time.", MsgBoxStyle.Information, MB_TITLE)
           Catch ex As InvalidOperationException
              MsgBox("This program is already running." & vbCrLf & _
              "To maximize performance of your computer only one instance of" & vbCrLf & _
              "this program can run at a time.", MsgBoxStyle.Information, MB_TITLE)
           End Try
  
        End If
  
     End Sub
  
  End Module

Hope it helps!

Robert Smith
Kirkland, WA

 

added to smithvoice October 2004


...
...

"In theory, theory and practice are the same. In practice, they are not." -Albert Einstein