Mattisdada
Mattisdada

Reputation: 997

Simulate .Net single instance application without using the single instance flag

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

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

Upvotes: 0

Views: 178

Answers (2)

SSS
SSS

Reputation: 5403

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

Upvotes: 1

JimH
JimH

Reputation: 13

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

Upvotes: 0

Related Questions