问题描述
我目前正在VB.NET中开发软件(使用Visual Studio 2019)。
我需要把程序放在最前面。 我正在使用此代码:
Private Sub BringInternet_Click(sender As Object,e As EventArgs) Handles BringInternet.Click
Dim mngcls As ManagementClass = New ManagementClass("Win32_Process")
Do
For Each instance As ManagementObject In mngcls.GetInstances()
If instance("Name").ToString = "msedge.exe" Then
Dim ID As Integer = instance("ProcessId")
MsgBox(ID)
AppActivate(ID)
Exit Do
End If
Next
Loop While False
End Sub
有时它可以正常工作,但大多数时候都无法工作。我已经对此进行了一些研究,但没有发现任何有关此bug的信息。
解决方法
自从我使用AppActivate
以来已经有一段时间了(早于VB6天)。显然,它只是SetForegroundWindow()
Win32函数的包装,这意味着它仅将窗口置于最前面(如果它已经处于 restored 状态),但是如果最小化则无法恢复
要还原窗口然后将其置于最前面,您需要先调用ShowWindow()
,然后再调用SetForegroundWindow()
。
首先,将此类添加到您的项目中:
Imports System.Runtime.InteropServices
Public Class ProcessHelper
<DllImport("User32.dll")>
Private Shared Function SetForegroundWindow(handle As IntPtr) As Boolean
End Function
<DllImport("User32.dll")>
Private Shared Function ShowWindow(handle As IntPtr,nCmdShow As Integer) As Boolean
End Function
<DllImport("User32.dll")>
Private Shared Function IsIconic(handle As IntPtr) As Boolean
End Function
Private Const SW_RESTORE As Integer = 9
Public Shared Sub BringProcessToFront(processName As String)
' Modern browsers run on multiple processes.
' We need to find the ones that have a WindowHandle.
Dim processes = Process.GetProcessesByName(processName).
Where(Function(p) p.MainWindowHandle <> IntPtr.Zero)
For Each p As Process In processes
If BringProcessToFront(p) Then Exit Sub
Next
End Sub
Public Shared Function BringProcessToFront(p As Process) As Boolean
Dim windowHandle As IntPtr = p.MainWindowHandle
If IsIconic(windowHandle) Then
ShowWindow(windowHandle,SW_RESTORE)
End If
Return SetForegroundWindow(windowHandle)
End Function
End Class
然后,您可以像这样使用它:
ProcessHelper.BringProcessToFront("msedge") ' Tip: Use the process name without ".exe".