【问题标题】:How to call COM object method from AHK如何从 AHK 调用 COM 对象方法
【发布时间】:2022-01-13 21:52:44
【问题描述】:

我对@9​​87654324@ 很陌生,我对COM 对象有疑问。

我想模仿的是Powershell one-liner:

(Get-WMIObject Win32_PnPEntity).GetDeviceProperties("DEVPKEY_Device_BusReportedDeviceDesc").DeviceProperties.Data

到目前为止,我的代码是这样的:

#NoEnv  ; Don't check empty variables to see if they are environment variables.
#Warn  ; Enable warnings.
#SingleInstance Force  ; Force single instance.
SendMode, Input  ; Send is an alias for SendInput. Faster and safer.
SetNumLockState, AlwaysOn  ; NumLock is always on, the key does not have any future effect.
SetWorkingDir, % A_Desktop
DetectHiddenWindows, On  ; Detect hidden windows, needed for PostMessage.

for device in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_PnPEntity")  {
    keys := ComObjArray(0xC, 1)  ; VT_VARIANT
    props := ComObjArray(0xC, 1)
    keys[0] := "DEVPKEY_Device_BusReportedDeviceDesc"
    result := device.GetDeviceProperties(keys, props)
    if (!result)
        MsgBox, % props[0]
}

函数调用返回0,据我所知是正确的。但是props 数组似乎是空的。

我认为我现在的问题是:props 是一个ByRef 变量,但我尝试使用一些我发现的代码来创建ByRef 变量(here)以获取返回值,但没有任何成功。

显然我在函数调用上做错了,因为我完全不知道如何使用来自AutoHotKeyCOM

是的,我知道我可以在这里使用setupapi.dll,或者一些第三方库,甚至是PowerShell one-liner,但是我正在尝试从AutoHotKey学习如何使用COM,如何调用@ 987654337@对象方法等

因此,非常感谢任何帮助。提前非常感谢。

Here is GetDeviceProperties function signature, for reference.

【问题讨论】:

  • 现在不要 AHK,但这里有一个 C# 版本,如果有帮助的话:stackoverflow.com/questions/69362886/…
  • 谢谢,西蒙。我已经知道如何在 C#(或 C 中)做到这一点,我的问题是在 AHK 中构建正确的类型、变量等,这很难做到。
  • 嗯,不确定 AHK,但据我了解,您不像我在 C# 中那样称呼它。尝试只传递一个参数,它是一个应该包含 2 个项目的 VARIANT 数组。第一项是 BSTR 数组,第二项是空的 VARIANT(返回时填充)
  • Simon,我不是故意使用InvokeMethod,因为我想学习如何直接调用COM对象方法。当然,如果我不能这样做,我将使用 InvokeMethod 或在 setupapi.dll 上使用 DLLCall 来完成。所有这些方法都有效,但我想学习这一点:) 但我会尝试你的建议,只使用一个参数,好主意。
  • Simon,我试过了,它似乎也不起作用。函数调用失败并出现错误信号,表明参数无效,因此问题不依赖于此。我想我遗漏了一些非常明显的东西,但我一辈子都看不到它。

标签: com autohotkey


【解决方案1】:

你可以这样做:

items := ComObjGet("winmgmts:").ExecQuery("Select * from Win32_PnPEntity")._NewEnum
    while items[device]
        MsgBox %        device.Availability[0]
            .   "`n"    device.Caption[0]
            .   "`n"    device.ClassGuid[0]
            ; . "`n"    device.CompatibleID[][0]
            .   "`n"    device.ConfigManagerErrorCode[0]
            .   "`n"    device.ConfigManagerUserConfig[0]
            .   "`n"    device.CreationClassName[0]
            .   "`n"    device.Description[0]
            .   "`n"    device.DeviceID[0]
            .   "`n"    device.ErrorCleared[0]
            .   "`n"    device.ErrorDescription[0]
            ; . "`n"    device.HardwareID[][0]
            .   "`n"    device.InstallDate[0]
            .   "`n"    device.LastErrorCode[0]
            .   "`n"    device.Manufacturer[0]
            .   "`n"    device.Name[0]
            .   "`n"    device.PNPClass[0]
            .   "`n"    device.PNPDeviceID[0]
            .   "`n"    device.PowerManagementCapabilities[][0]
            .   "`n"    device.PowerManagementSupported[0]
            .   "`n"    device.Present[0]
            .   "`n"    device.Service[0]
            .   "`n"    device.Status[0]
            .   "`n"    device.StatusInfo[0]
            .   "`n"    device.SystemCreationClassName[0]
            .   "`n"    device.SystemName[0]
                            
End::
ExitApp

注释行在这里给出错误...您可以取消注释并根据需要进行测试。

【讨论】:

  • OP 正在尝试使用某些特定参数调用 ComObject 上的方法,这绝不相关。所有这些字段在正常的 for 循环实现中已经可用,您在这里所做的只是手动调用 _NewEnum 而不是让 for 循环负责调用它。
  • 谢谢 Dieisson,但这不是我需要的。我知道我可以遍历 ComObjGet() 的结果,问题不是访问返回项的属性,而是调用方法。
猜你喜欢
  • 1970-01-01
  • 2011-09-25
  • 2013-03-23
  • 2014-09-29
  • 2017-01-02
  • 1970-01-01
  • 2011-03-05
  • 2012-03-22
  • 2015-02-03
相关资源
最近更新 更多