我正在尝试在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
和那个输出:
所以,上面没有用,可能是因为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):
感谢![/ p>
编辑:小心,事实证明,如果导致另一个应用程序以最小化方式进入前台的应用程序,则无法将另一个应用程序带到前台。我还需要枚举Alt-Tab程序组中的应用程序,并以一种强制窗口到前台的方式使用api,而不是单独使用AppActivate或SetForeGroundWindow()。
答案 0 :(得分:2)
你必须:
枚举所有正在运行的进程,查看其完整路径和文件名,直到找到您感兴趣的进程为止。请使用EnumProcesses()
或CreateToolhelp32Snapshot()
。有关示例,请参阅Enumerating All Processes和Taking a Snapshot and Viewing Processes。找到所需的文件名后,您将知道其进程ID。
使用EnumWindows()
和GetWindowThreadProcessId()
枚举所有顶级窗口,查找属于同一进程ID的窗口。然后,您可以根据需要恢复这些窗口(如果您有权这样做,那就是 - 请参阅SetForegroundWindow()
文档中提到的所有限制)。如果窗口最小化,您可以尝试向其发送WM_SYCOMMAND
/ SC_RESTORE
消息。但是如果窗口已经非最小化但只是没有聚焦,那么你可能会遇到阻力,试图以可编程的方式集中注意力。