Jerry
Jerry

Reputation: 13

Restore Application from SysTray rather than launch NEW instance?

Does anyone know how to get an already running instance of an application (minimized to systray) to restore rather than have a new instance run?

I have adjusted the project properties to "Make single instance application". This is great at preventing a new application from launching but does not restore the already running instance.

I am using VB.NET in Visual Studio Express 2012 on Windows 7 Pro SP1.

I do not have any code yet for this, however here is the code that I have used to minimize to tray (as found on this great forum) in case it is relevant:

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
    Me.WindowState = FormWindowState.Minimized
    Me.Visible = False
    e.Cancel = True
    nfi.Visible = True
End Sub

Private Sub ShowWindowToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShowWindowToolStripMenuItem.Click
    nfi.Visible = False
    Me.WindowState = FormWindowState.Maximized
    Me.Visible = True
End Sub

Upvotes: 0

Views: 452

Answers (2)

Hans Passant
Hans Passant

Reputation: 942099

Use the StartupNextInstance event, it fires when your program is started again.

Project + Properties, Application tab, click the View Application Events button. In the upper left combobox at the top of the editor window select (MyApplication Events). In the right combobox select "StartupNextInstance". Make it look similar to this:

Partial Friend Class MyApplication
    Private Sub MyApplication_StartupNextInstance(sender As Object, e As ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
        Form1.Show()
    End Sub
End Class

Upvotes: 2

Piratica
Piratica

Reputation: 483

The best way I can think of is to make sure that if any other instance is launched, new instance can alert the user of it.

You should be able to use this code:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim ProcessName As String = Process.GetCurrentProcess.ProcessName.ToString()
    Dim AllProcesses As List(Of System.Diagnostics.Process) = Process.GetProcessesByName(ProcessName).ToList()
    Dim ToKillNow As List(Of System.Diagnostics.Process) = OtherProcesses(AllProcesses)
    If IsAlreadyRunning() Then
        If vbOK = MsgBox("There are already one or more windows of this program running, you can terminate the window(s) now and continue running this one by pressing 'Ok'. Otherwise, click 'Cancel' and you can use the other one(s).", MsgBoxStyle.OkCancel, "Another Instance of This Program is Running") Then
            'Updates the list, more instances may have been started since we last checked
            AllProcesses = Process.GetProcessesByName(ProcessName).ToList()
            ToKillNow = OtherProcesses(AllProcesses)
            'Do the actual killing
            For Each Item In ToKillNow
                If Not Item.HasExited = True Then
                    Item.Kill()
                End If
            Next
        Else
            End
        End If
    End If
End Sub

Public Function IsAlreadyRunning()
    Dim ProcessName As String = Process.GetCurrentProcess.ProcessName.ToString()
    Dim AllProcesses As List(Of System.Diagnostics.Process) = Process.GetProcessesByName(ProcessName).ToList()
    Dim CurrentProcessId As Integer = Process.GetCurrentProcess.Id
    For Each p As Process In AllProcesses
        If Not p.Id = CurrentProcessId Then
            Return True
        End If
    Next
    Return False
End Function

Public Function OtherProcesses(ByVal ListOfProcesses As List(Of System.Diagnostics.Process))
    Dim ToKillNow As New List(Of System.Diagnostics.Process)
    Dim CurrentProcessId As Integer = Process.GetCurrentProcess.Id
    For Each Item In ListOfProcesses
        If Not Item.Id = CurrentProcessId Then
            ToKillNow.Add(Item)
        End If
    Next
    Return ToKillNow
End Function

Hope this helps :)

Upvotes: 1

Related Questions