Reputation: 91
I am trying to reopen an exe file (that I have previously opened) in this way: If it is open, then DO NOT reopen it but just bring that file into foucs. If it is not open, then open it. (Right now - the exe file keeps reopening.)
Anyone have a clue how to do this? (It works for powerpoint files, word files, excel files, movie files, pdf files)
This is my code:
Dim file3dopen As New ProcessStartInfo()
With file3dopen
.FileName = Add3DFolder & cmbx3D.Text
.UseShellExecute = True
'Minimizes this form and unhides other form
Minimize()
FormMain.Show()
FormMain.TopMost = True
End With
Process.Start(file3dopen)
Upvotes: 1
Views: 1063
Reputation: 216302
If you own the code for the application that you want to start, then the best thing to do is to change that application startup code to not allow two instances of the same application. This could be done using the Mutex object in this way
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<STAThread()> _
Shared Sub Main()
Dim createdNew As Boolean = true;
Using mutes = new Mutex(true, "MyApplicationName", createdNew)
if createdNew Then
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(false)
Application.Run(new MainForm())
else
Dim current = Process.GetCurrentProcess();
for each process in Process.GetProcessesByName(current.ProcessName)
if process.Id <> current.Id Then
SetForegroundWindow(process.MainWindowHandle)
Exit For
End If
Next
End If
End Using
After this, your other app can launch the first app without any check because in the called app the code above discover another copy of itself and switch the control to the copy found. There will never be two copies of the same application running at one time.
Instead, if you don't own the application to be started, then you can only work on your code adding a test to see if the application Process Name is present in the list of the current running processes For example:
Private Sub TestIfRunningIE
if IsApplicationRunning("IEXPLORE") Then
Console.WriteLine("Internet Explorer is running")
Else
Console.WriteLine("Internet Explorer is NOT running")
End If
End Sub
Public Function IsApplicationRunning(ByVal appName As String) As Boolean
For Each aProcess in Process.GetProcesses()
If aProcess.ProcessName.StartsWith(appName, StringComparisong.CurrentCultureIgnoreCase) Then
Return true
End If
Next
Return False
End Function
Of course this requires that you know the process name, but you can easily find that name using one of the innumerable free process utility available.
EDIT To bring the process found to the foreground we need a bit of help from WinAPI. First, change the IsApplicationRunning to return the process found
Public Function IsApplicationRunning(ByVal appName As String) As Process
For Each aProcess in Process.GetProcesses()
If aProcess.ProcessName.StartsWith(appName, StringComparisong.CurrentCultureIgnoreCase) Then
Return aProcess
End If
Next
Return Nothing
End Function
then build a class that contains the declaration of two WinAPI contained in user32.dll
Public Class Win32Helper
<System.Runtime.InteropServices.DllImport("user32.dll", _
EntryPoint:="SetForegroundWindow", _
CallingConvention:=Runtime.InteropServices.CallingConvention.StdCall, _
CharSet:=Runtime.InteropServices.CharSet.Unicode, SetLastError:=True)> _
Public Shared Function _
SetForegroundWindow(ByVal handle As IntPtr) As Boolean
End Function
<System.Runtime.InteropServices.DllImport("user32.dll", _
EntryPoint:="ShowWindow", _
CallingConvention:=Runtime.InteropServices.CallingConvention.StdCall, _
CharSet:=Runtime.InteropServices.CharSet.Unicode, SetLastError:=True)> _
Public Shared Function ShowWindow(ByVal handle As IntPtr, ByVal nCmd As Int32) As Boolean
End Function
End Class
and now in your main code write this
Dim proc = IsApplicationRunning("your_process_name")
if proc isnot Nothing then
Dim handle As IntPtr = proc.MainWindowHandle
Dim Win32Help As New Win32Helper
If Not IntPtr.Zero.Equals(handle) Then
Win32Helper.ShowWindow(handle, 1)
Win32Helper.SetForegroundWindow(handle)
End If
else
Console.WriteLine("Process not found")
End if
As a reference, I have found the code to implement the Win32Helper class here
Upvotes: 1