无法将流程置于最前面

问题描述

我目前正在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".