在Windows 7中,以下Excel VBA 7.1代码段成功启动了屏幕键盘(OSK.EXE),但从“ proc”(过程信息)参数(通过ByRef)检索的dwProcessID成员的值不匹配或任务管理器显示的任何其他PID。
Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long ' Integer doesn't work either
dwThreadID As Long
End Type
Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As _
PROCESS_INFORMATION) As Long
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
start.cb = Len(start)
If CreateProcessA(0, "OSK.EXE", 0, 0, 1, NORMAL_PRIORITY_CLASS, 0, 0, start,
proc) <> 0 Then
WaitForInputIdle proc.hProcess, INFINITE
MsgBox CStr(proc.dwProcessID), vbInformation, "Process ID" ' Wrong for
OSK, but correct for Notepad and Calc
CloseHandle (proc.hProcess)
CloseHandle (proc.hThread)
End If
对于OSK,似乎proc.hProcess值不正确。我对照“任务管理器”中为OSK列出的PID检查了proc.dwProcessID的进程ID值,但它们不匹配。实际上,没有为任何进程列出proc.dwProcessID(即使在Process Explorer中),因此似乎PROCESS_INFORMATION类型没有收到正确的输出。
一切对于NOTEPAD和CALC都可以正常工作。在VB.NET中编译的等效代码在OSK上可以正常运行,那么,导致CreateProcessA在OSK上无法正常工作的VBA有何不同?
预先感谢, 约翰。
答案 0 :(得分:1)
可能是您正在启动的可执行文件(OSK.EXE)执行了另一个进程或执行了一些工作并很快退出,因此当您查看进程资源管理器时,您什么也找不到。 如果“ if”中的代码未执行,我将尝试通过GetLastError调用获取错误。
答案 1 :(得分:1)
我认为您遇到的问题是https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/64-bit-visual-basic-for-applications-overview。 长不是替代指针的好方法,在这种情况下应该是
Type PROCESS_INFORMATION
hProcess As LongPtr
hThread As LongPtr
dwProcessID As Long
dwThreadID As Long
End Type
Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As LongPtr, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As LongPtr, ByVal lpThreadAttributes As LongPtr, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As LongPtr, ByVal lpCurrentDirectory As LongPtr, _
ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As _
PROCESS_INFORMATION) As Long