当前位置: 首页 > 面试题库 >

从Go查询WMI

伯君浩
2023-03-14
问题内容

我想从Go运行WMI查询。有几种方法可以从Go 调用DLL函数。我的理解是,在某个地方必须有一些DLL,通过正确的调用,它将返回一些我可以解析和使用的数据。我宁愿避免调用C或C
++,尤其是因为我猜想它们是Windows API本身的包装。

我检查了的输出dumpbin.exe /exports c:\windows\system32\wmi.dll,以下条目看起来很有希望:

WmiQueryAllDataA (forwarded to wmiclnt.WmiQueryAllDataA)

但是我不确定从这里做什么。此函数采用什么参数?它返回什么?搜索WmiQueryAllDataA没有帮助。并且该名称仅出现在的注释中c:\program files (x86)\windows kits\8.1\include\shared\wmistr.h,但没有函数签名。

有更好的方法吗?还有另一个DLL吗?我想念什么吗?我应该只使用C包装器吗?

使用.NET
Reflector在Linqpad中运行WMI查询显示了WmiNetUtilsHelper:ExecQueryWmi(和_f版本)的使用,但都没有可见的实现。

更新:
使用github.com/StackExchange/wmi软件包,该软件包在接受的答案中使用解决方案。


问题答案:

从C
++刚刚起步的新世纪开始,您就来到了COM的美好世界,即C语言中的面向对象编程。

在github上,mattn 在Go中集成了一个小包装,我曾经使用它包装了一个快速的示例html" target="_blank">程序。“
这个存储库是为实验而创建的,应该被认为是不稳定的。 ”灌输了各种各样的信心。

我省去了很多错误检查。当我说时,请相信我,您将想要重新添加。

package main

import (
        "github.com/mattn/go-ole"
        "github.com/mattn/go-ole/oleutil"
)

func main() {
    // init COM, oh yeah
    ole.CoInitialize(0)
    defer ole.CoUninitialize()

    unknown, _ := oleutil.CreateObject("WbemScripting.SWbemLocator")
    defer unknown.Release()

    wmi, _ := unknown.QueryInterface(ole.IID_IDispatch)
    defer wmi.Release()

    // service is a SWbemServices
    serviceRaw, _ := oleutil.CallMethod(wmi, "ConnectServer")
    service := serviceRaw.ToIDispatch()
    defer service.Release()

    // result is a SWBemObjectSet
    resultRaw, _ := oleutil.CallMethod(service, "ExecQuery", "SELECT * FROM Win32_Process")
    result := resultRaw.ToIDispatch()
    defer result.Release()

    countVar, _ := oleutil.GetProperty(result, "Count")
    count := int(countVar.Val)

    for i :=0; i < count; i++ {
        // item is a SWbemObject, but really a Win32_Process
        itemRaw, _ := oleutil.CallMethod(result, "ItemIndex", i)
        item := itemRaw.ToIDispatch()
        defer item.Release()

        asString, _ := oleutil.GetProperty(item, "Name")

        println(asString.ToString())
    }
}

真正的问题是对ExecQuery的调用,我碰巧从可用的类中获取Win32_Process,因为它易于理解和打印。

在我的机器上,将打印:

System Idle Process
System
smss.exe
csrss.exe
wininit.exe
services.exe
lsass.exe
svchost.exe
svchost.exe
atiesrxx.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
spoolsv.exe
svchost.exe
AppleOSSMgr.exe
AppleTimeSrv.exe
... and so on
go.exe
main.exe

我不是在提升运行状态或未禁用UAC的情况下运行,但某些WMI提供程序将需要特权用户。

我也不是100%不会漏掉一点,您需要深入研究一下。COM对象是按引用计数的,因此defer应该很合适(前提是该方法长期运行不会疯狂),但是go-
ole可能有一些我没注意到的魔术。



 类似资料:
  • 问题内容: 在Python中 我试过了: 运行GetAll时出现错误“数据存储:空种类” 我也尝试过: 我收到错误“数据存储:空查询类型” 在此先感谢您的帮助。 问题答案: 至少在目前,Rich Churcher的评论似乎是正确的。 我认为Go中不支持Python无亲祖先查询。有一会儿,我以为您可以使用祖先键的Kind()方法,然后我又喝了些咖啡,然后感觉到了。

  • 这是我在mongodb go驱动程序中的功能: 这个函数运行得很好,但我在结果中得到了字段。我知道mongodb查询可以从查询结果中排除字段,但我不知道如何将其与函数一起使用: 从tutorialspoint: db。删除DDEMO。查找({},{u id:0}); 来自没有字段名的mongodb查询结果 db.collection.find ({},{_id: 0,t_number: 1}).

  • 问题内容: 在我的代码中,我正在使用。 然后,我执行该方法以填充准备好的语句的通配符。 在调用该方法并执行查询之前,我是否有办法检索(并打印出)最终查询?我只想将此用于调试目的。 问题答案: 这在JDBC API合同中没有定义,但是如果幸运的话,有问题的JDBC驱动程序可以通过调用来返回完整的SQL 。即 以我的经验,至少这样做是PostgreSQL 8.x和MySQL 5.x JDBC驱动程序。

  • 我想按标题做一个查询,如下所示: 问题是标题列字符集是latin1,而我的Java文件编码是UTF8。当title变量包含特殊字符(如重音)时,查询永远不会找到结果。 我使用的是MySQL数据库,连接url是: jdbc:mysql://mysite:3306/mydatabase?autorreconnect=true&characterencoding=latin1&useoldaliasMe

  • 问题内容: 我正在尝试使用sql语句从XML文档中获取特定数据。该文件如下: 我输入了sql查询以获取球体中值,如下所示: 但是我出错了 [错误]执行(4:17):ORA-19228:XPST0008-未声明的标识符:前缀’nsREF’本地名称’nsREF:Measure’ 您能帮我获得正确的价格吗 问题答案: Oracle安装程序 查询 : 输出 :

  • 我正试图从firebase数据库中获取项目列表。。。但我很难得到它们。我的代码大致如下: 应该返回我的项目的方法如下所示: GetItems()总是返回一个空列表,这有点道理,因为在我返回这个列表之前,没有什么可以触发onDataChange事件,所以我的问题是。。。如何使用此方法从DB返回项目列表?