如果在vb6中使用api运行特定程序'path \ app.exe',请将其带到前台

时间:2015-12-22 19:09:55

标签: winapi vb6

我正在尝试在vb6中使用api函数,这将允许我将程序带到前台(如果它正在运行)。此时我将使用sendkeys将关键笔划发送到相关程序。

踢球者是我唯一知道的程序是它的路径和.exe名称。例如,'c:\ anyfolder \ anyprog.exe'。

如果我知道有关该程序的其他信息,我可以找到有关如何执行此操作的各种信息,但如果我只知道上述内容,则无法找到(甚至不是标题栏在前台时所说的内容,即程序本身经常变化。)

有办法做到这一点吗?

到目前为止,在Remy的帮助下,我有了这个vb6代码,我尝试将C代码从Taking a Snapshot and Viewing Processes转换为vb6。但它不是很有效,有什么想法吗?

Private Sub FillLists_Click()
   PathList.Clear
   FileNameList.Clear
   Dim p As Long
   Dim m As Long
   Dim ml As Long
   Dim hProcessSnapshot As Long
   Dim h As Long
   Dim hl As Long
   Dim uProcess As PROCESSENTRY32
   Dim uModule As MODULEENTRY32

   hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
   If hProcessSnapshot = 0 Then Exit Sub

   uProcess.dwSize = Len(uProcess)
   p = ProcessFirst(hProcessSnapshot, uProcess)
   Do While p 'as long as p is not 0
      h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, uProcess.th32ProcessID)
      hl = GetLastError()

      uModule.dwSize = Len(uModule)
      m = Module32First(h, uModule)
      ml = GetLastError()

      PathList.AddItem "h=" & h & " hl=" & hl & " m=" & m & " ml=" & ml & uModule.szModule

      FileNameList.AddItem uProcess.szExeFile

      Call CloseHandle(h)
      p = ProcessNext(hProcessSnapshot, uProcess)
   Loop
   Call CloseHandle(hProcessSnapshot)
End Sub

和那个输出:

enter image description here

所以,上面没有用,可能是因为vb6是32位而我的电脑是Win7 64位。我在谷歌搜索俄罗斯论坛帖子中的'vb6 QueryFullProcessImageName'时发现了这个功能,无法读取评论,但代码是金色的!

Function GetProcessNameByPID(pid As Long) As String
    Const PROCESS_QUERY_LIMITED_INFORMATION As Long = &H1000
    Const PROCESS_QUERY_INFORMATION         As Long = &H400
    Const MAX_PATH                          As Long = 260
    Dim hProc               As Long
    Dim Path                As String
    Dim lStr                As Long
    Dim inf(68)             As Long
    Dim IsVistaAndLater     As Boolean
    inf(0) = 276: GetVersionEx inf(0): IsVistaAndLater = inf(1) >= 6
    If Not IsVistaAndLater Then Exit Function
    hProc = OpenProcess(IIf(IsVistaAndLater, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_QUERY_INFORMATION), False, pid)
    If hProc <> 0 Then 'INVALID_HANDLE_VALUE Then
        lStr = MAX_PATH
        Path = Space(lStr)
        ' minimum Windows Vista !!!!!!!
        If QueryFullProcessImageName(hProc, 0, StrPtr(Path), lStr) Then
            GetProcessNameByPID = Left$(Path, lStr)
        End If
        CloseHandle hProc
    End If
End Function

现在我的代码是:

Private Sub FillLists_Click()
   PathList.Clear
   FileNameList.Clear
   Dim p As Long
   Dim hProcessSnapshot As Long
   Dim uProcess As PROCESSENTRY32

   hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
   If hProcessSnapshot = 0 Then Exit Sub

   uProcess.dwSize = Len(uProcess)
   p = ProcessFirst(hProcessSnapshot, uProcess)
   Do While p 'as long as p is not 0

      PathList.AddItem GetProcessNameByPID(uProcess.th32ProcessID)

      FileNameList.AddItem uProcess.szExeFile

      p = ProcessNext(hProcessSnapshot, uProcess)
   Loop
   Call CloseHandle(hProcessSnapshot)
End Sub

AND的输出是(当你找到你想要的那个时,剩下的就是做一个AppActivate uProcess.th32ProcessID):

enter image description here

感谢![/ p>

编辑:小心,事实证明,如果导致另一个应用程序以最小化方式进入前台的应用程序,则无法将另一个应用程序带到前台。我还需要枚举Alt-Tab程序组中的应用程序,并以一种强制窗口到前台的方式使用api,而不是单独使用AppActivate或SetForeGroundWindow()。

1 个答案:

答案 0 :(得分:2)

你必须:

  1. 枚举所有正在运行的进程,查看其完整路径和文件名,直到找到您感兴趣的进程为止。请使用EnumProcesses()CreateToolhelp32Snapshot()。有关示例,请参阅Enumerating All ProcessesTaking a Snapshot and Viewing Processes。找到所需的文件名后,您将知道其进程ID。

  2. 使用EnumWindows()GetWindowThreadProcessId()枚举所有顶级窗口,查找属于同一进程ID的窗口。然后,您可以根据需要恢复这些窗口(如果您有权这样做,那就是 - 请参阅SetForegroundWindow()文档中提到的所有限制)。如果窗口最小化,您可以尝试向其发送WM_SYCOMMAND / SC_RESTORE消息。但是如果窗口已经非最小化但只是没有聚焦,那么你可能会遇到阻力,试图以可编程的方式集中注意力。