从Go查询WMI

我想从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中集成了一个小包装,我曾经使用它包装了一个快速的示例程序。“

这个存储库是为实验而创建的,应该被认为是不稳定的。 ”灌输了各种各样的信心。

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

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可能有一些我没注意到的魔术。

以上是 从Go查询WMI 的全部内容, 来源链接: utcz.com/qa/427400.html

回到顶部