从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 mainimport (
"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 ProcessSystem
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