0

At the moment I'm trying to build a singleton application without using the "Single Instance" flag, this is due to some of the mechanisms of the application actually requires multiple instances (self updater,etc). So I have to build my own method of insuring that there is only one instance of the application.

I've gotten about halfway through creating this, I've gotten to the point of

  • Detects how many instances are running
  • A method to show the other instances Main Window (this is where I'm stuck)

The problem is the application most of the time runs in the background, hidden, with no item in the taskbar. When calling process.MainWindowHandle, it always returns 0, as for that function to detect the current "MainWindow" it requires the window to be A) Visible and B) Showing in taskbar.

Is there anyway around this limitation?

A method I can think of, but have no idea of implementing is to store the MainWindowHandle the first time the application is visible, but how would i expose this value?

Current code:

            Dim running_processes As Process() = Process.GetProcessesByName("helpdesk")
            Dim current_process_id As Integer = Process.GetCurrentProcess().Id

            If (running_processes.Length = 1) Then
                'Run the app like normal
                bootstrap_loader.Show()


            Else
                For Each process As Process In running_processes
                    If process.Id = current_process_id Then Continue For

                    'MainWindowHandle returns 0 when window is not visible
                    'Sidenote: ShowWindow is from user32.dll :) 
                    ShowWindow(process.MainWindowHandle, SHOW_WINDOW.SW_NORMAL)

                    'Exit the application like a baws
                    'Environment.Exit(2)
                Next
            End If
Mattisdada
  • 979
  • 1
  • 15
  • 24

2 Answers2

1

At app start, open a temp file and keep it open. Also at startup, test if you can delete the temp file. If not, then another instance is running, so then your app shuts down.

Imports System.IO

Public Class Form1
  Private mstrLockFilename As String
  Private mfstLock As FileStream

  Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    mstrLockFilename = Application.StartupPath & "\lock.txt"
    Try
      mfstLock = New FileStream(mstrLockFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)
    Catch ex As Exception
      MsgBox("App is already running", MsgBoxStyle.Exclamation)
      End
    End Try
  End Sub

  Private Sub Form1_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
    If mfstLock IsNot Nothing Then
      mfstLock.Close()
      mfstLock.Dispose()
      Try
        File.Delete(mstrLockFilename)
      Catch
      End Try
    End If
  End Sub
End Class
SSS
  • 4,807
  • 1
  • 23
  • 44
  • The detection code looks good! But the problem is my detection is working fine, but its the "Showing the window if application is already running" part that is broken(the second piece of the "Single instance application" puzzle). But your answer does give me an idea I could try. – Mattisdada Feb 06 '13 at 06:12
  • Better to create a mutex rather than a clunky lock file or using the Process list to see if you app is already running. – Chris Dunaway Feb 06 '13 at 15:30
  • @Chris, already using the process list method, but what I'll try and do is combine this method and in the lock file contain the mainwindowhandler, apart from that, I have no idea how to send that info (I'd love to get it straight from the program some how, rather than dealing with lock files/temp files/etc) – Mattisdada Feb 06 '13 at 22:33
0

Before they had the Single Instance option you had to do it yourself. Basically - you can make a call to the the current apps name - then a call to get all running apps by that name.

Here are a few links (if I can post them).

Vb Helper

C code but can be translated

Vb Net Code

I saw one reference that indicated this may not work where both calls are at the same time. Pehaps that can be fixed by two calls. Early in the loading - then later on.

Hope this helps

Community
  • 1
  • 1
JimH
  • 13
  • 3