【问题标题】:Cannot bring a process to the front不能把进程带到前面
【发布时间】:2020-08-18 14:51:01
【问题描述】:

我目前正在使用 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

有时它会起作用,但大多数时候它不起作用。我已经对此进行了一些研究,但我没有发现有关此错误的任何信息。

【问题讨论】:

  • 首先,Do...While 循环的意义何在?无论如何它只会运行一次。
  • 找到进程后退出。否则我有一个错误,因为我尝试多次调用同一个进程。
  • 您可以删除 Do...While 并只删除 For Each 循环上的 Exit For
  • 再一次,你的Do...While 循环只会运行一次(因为Loop While False)。你应该改变条件(如果你真的需要循环;但我认为你不需要它)或者你应该摆脱它并使用Exit For而不是Exit Do
  • 令人惊讶的是它的工作原理,Edge 是一个 UWP 应用程序。请改用Process.Start("microsoft-edge:")Backgrounder

标签: .net vb.net process


【解决方案1】:

我使用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".

【讨论】:

  • 谢谢。这是工作。我被屏蔽了两天。
猜你喜欢
  • 2011-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多