【问题标题】:CreateProcess not retrieving correct PID for OSKCreateProcess 没有为 OSK 检索正确的 PID
【发布时间】:2018-12-06 15:13:19
【问题描述】:

在 Windows 7 中,以下 Excel VBA 7.1 sn-p 成功启动了屏幕键盘 (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 中正常运行,那么 VBA 有什么不同导致 CreateProcessA 无法在 OSK 中正常运行?

提前致谢, 约翰。

【问题讨论】:

    标签: excel vba createprocess on-screen-keyboard


    【解决方案1】:

    可能是您正在启动的可执行文件 (OSK.EXE) 执行另一个进程或执行某些工作并很快退出,因此当您查看进程资源管理器时,您找不到任何东西。 如果“if”中的代码没有执行,我会尝试使用 GetLastError 调用来获取错误。

    【讨论】:

    • 感谢您的建议。 'if' 语句中的代码被执行,OSK 仍然按要求运行,但 CreateProcess 为 OSK 生成一个与任务管理器中显示的不同的句柄。没有错误被标记。如果在 VB.NET 中编译相同的代码会正常运行,因此该问题似乎与 VBA 运行方式不同的问题有关。
    【解决方案2】:

    我认为您遇到了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

    声明函数 CreateProcessA Lib "kernel32" (ByVal _ lpApplicationName 作为 LongPtr,ByVal lpCommandLine 作为字符串,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) 只要

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      相关资源
      最近更新 更多