如果您拥有要启动的应用程序的代码,那么最好的办法是更改该应用程序启动代码以不允许同一应用程序的两个实例。这可以通过这种方式使用 Mutex 对象来完成
<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
在此之后,您的其他应用程序无需任何检查即可启动第一个应用程序,因为在被调用的应用程序中,上面的代码发现了自身的另一个副本并将控件切换到找到的副本。永远不会有同一应用程序的两个副本同时运行。
相反,如果您不拥有要启动的应用程序,那么您只能在代码上添加测试以查看应用程序进程名称是否存在于当前正在运行的进程列表中例如:
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
当然,这要求您知道进程名称,但您可以使用无数可用的免费进程实用程序之一轻松找到该名称。
编辑
要将发现的进程带到前台,我们需要 WinAPI 的一些帮助。首先,更改 IsApplicationRunning 以返回找到的进程
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
然后构建一个类,其中包含两个 WinAPI 的声明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
现在在你的主要代码中写这个
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
作为参考,我在这里找到了实现 Win32Helper 类的代码