首页 > 解决方案 > CreateProcess 没有为 OSK 检索正确的 PID

问题描述

在 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 有何不同?

在此先感谢,约翰。

标签: excelvbacreateprocesson-screen-keyboard

解决方案


我认为您遇到了诸如https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/64-bit-visual-basic-for-applications-overview之类的问题。Long 不是指针的好替代品,在这种情况下应该是

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

另见https://www.jkp-ads.com/articles/apideclarations.asp


推荐阅读