英文:
How can I use the go language to specify the namespace of wmi when calling wmi?
问题
我可以帮你翻译代码部分,以下是翻译好的内容:
我被要求使用Go语言获取本地计算机的一些计算机配置,例如CPU型号和内存大小,但在获取某些配置时遇到了问题。
当我获取基本的CPU信息时,我使用以下代码,它能正常工作,因为Win32_Processor
来自root\cimv2
:
type cpuInfo struct {
Name string
NumberOfCores uint32
ThreadCount uint32
Architecture uint32
}
func getCPUInfo() {
var cpuinfo []cpuInfo
err := wmi.Query("Select * from Win32_Processor", &cpuinfo)
if err != nil {
return
}
fmt.Printf("Cpu info =", cpuinfo)
fmt.Println()
}
但是当我需要获取一些特殊信息时,例如网络适配器是否为物理网络适配器,硬盘是SSD还是HDD,我需要使用MSFT_NetAdapter
和MSFT_PhysicalDisk
,它们的命名空间不是root\cimv2
,而是来自root\StandardCimv2
和\root\microsoft\windows\storage
。
当我使用以下代码获取这些信息时,返回的值为空:
type networkInfo struct {
Name string
DriverDescription string
InterfaceName string
}
func getNetworkInfo() {
var networkinfo []networkInfo
query := wmi.CreateQuery(&networkinfo, "Select * from MSFT_NetAdapter where Virtual=false")
err := wmi.QueryNamespace(query, &networkinfo, "Root\\StandardCimv2")
if err != nil {
return
}
fmt.Printf("Network Info=", networkinfo)
fmt.Println()
}
当我使用C#调用这个类时,我能正确获取到所需的信息:
var objectSearcher = new ManagementObjectSearcher("root\\StandardCimv2", $@"select DriverDescription, Name, InterfaceName, InterfaceType, NdisPhysicalMedium from MSFT_NetAdapter where ConnectorPresent=1"); //Physical adapter
foreach (var managementObject in objectSearcher.Get())
{
var interfaceName = managementObject["InterfaceName"]?.ToString();
var interfaceType = Convert.ToUInt32(managementObject["InterfaceType"]);
var ndisPhysicalMedium = Convert.ToUInt32(managementObject["NdisPhysicalMedium"]);
var driverDescription = managementObject["DriverDescription"]?.ToString();
var name = managementObject["Name"]?.ToString();
if (!string.IsNullOrEmpty(interfaceName) &&
interfaceType == 6 &&
(ndisPhysicalMedium == 0 || ndisPhysicalMedium == 14)) //802.3
{
Console.WriteLine("Name:" + name);
Console.WriteLine("DriverDescription:" + driverDescription);
Console.WriteLine("InterfaceName:" + interfaceName);
}
}
请问我应该如何在Go语言中指定命名空间来调用所需的类?
英文:
I was asked to use the Go language to obtain some computer configurations of the local computer, such as CPU model and memory size,but there was a problem when getting some configurations.
When I get the basic CPU information, I use the following code, which works well because Win32_ Processor
from root\cimv2
type cpuInfo struct {
Name string
NumberOfCores uint32
ThreadCount uint32
Architecture uint32
}
func getCPUInfo() {
var cpuinfo []cpuInfo
err := wmi.Query("Select * from Win32_Processor", &cpuinfo)
if err != nil {
return
}
fmt.Printf("Cpu info =", cpuinfo)
fmt.Println()
}
But when I need to obtain some special information, such as whether the network card is a physical network card, whether the hard disk is SSD or HDD, I need to use MSFT_ NetAdapter
and MSFT_ PhysicalDisk
, whose namespaces are not root\cimv2
,They come from root\StandardCimv2
and \root\microsoft\windows\storage
.
When I use the following code to obtain this information, the returned value is null
type networkInfo struct {
Name string
DriverDescription string
InterfaceName string
}
func getNetworkInfo() {
var networkinfo []networkInfo
query := wmi.CreateQuery(&networkinfo, "Select * from MSFT_NetAdapter where Virtual=false")
err := wmi.QueryNamespace(query, &networkinfo, "Root\\StandardCimv2")
if err != nil {
return
}
fmt.Printf("Network Info=", networkinfo)
fmt.Println()
}
When I use C# to call this class, I get the information I need correctly
var objectSearcher = new ManagementObjectSearcher("root\\StandardCimv2", $@"select DriverDescription, Name, InterfaceName, InterfaceType, NdisPhysicalMedium from MSFT_NetAdapter where ConnectorPresent=1"); //Physical adapter
foreach (var managementObject in objectSearcher.Get())
{
var interfaceName = managementObject["InterfaceName"]?.ToString();
var interfaceType = Convert.ToUInt32(managementObject["InterfaceType"]);
var ndisPhysicalMedium = Convert.ToUInt32(managementObject["NdisPhysicalMedium"]);
var driverDescription = managementObject["DriverDescription"]?.ToString();
var name = managementObject["Name"]?.ToString();
if (!string.IsNullOrEmpty(interfaceName) &&
interfaceType == 6 &&
(ndisPhysicalMedium == 0 || ndisPhysicalMedium == 14)) //802.3
{
Console.WriteLine("Name:" + name);
Console.WriteLine("DriverDescription:" + driverDescription);
Console.WriteLine("InterfaceName:" + interfaceName);
}
}
How should I use the Go language to specify the namespace to call the class I need?
答案1
得分: 1
你正在错误地使用wmi.CreateQuery()函数。请查看https://github.com/StackExchange/wmi/blob/v1.2.1/wmi.go#L566上的参数描述。
你需要在getNetworkInfo()函数中替换你的查询语句:
query := wmi.CreateQuery(&networkinfo, "Virtual=false", "MSFT_NetAdapter")
err := wmi.QueryNamespace(query, &networkinfo, "Root\\StandardCimv2")
而在wmi.QueryNamespace()函数中,写Root或root没有任何区别。我已经验证过了。
英文:
You are using the function wmi.CreateQuery() incorrectly. See the parameters description on https://github.com/StackExchange/wmi/blob/v1.2.1/wmi.go#L566.
You must replace your query in getNetworkInfo():
query := wmi.CreateQuery(&networkinfo, "Virtual=false", "MSFT_NetAdapter")
err := wmi.QueryNamespace(query, &networkinfo, "Root\\StandardCimv2")
And it makes absolutely no difference whether to write Root or root in wmi.QueryNamespace(). I checked.
答案2
得分: 0
感谢@AlexandrKamenev!我确定我得到了我想要的答案。使用QueryNamespace()方法来指定命名空间:
直接使用QueryNamespace()方法:
err := wmi.QueryNamespace("Select * from MSFT_PhysicalDisk", &diskMediaTypeInfo, "root\\Microsoft\\Windows\\Storage")
使用CreateQuery()和QueryNamespace()方法:
query := wmi.CreateQuery(&networkinfo, "WHERE Virtual=false", "MSFT_NetAdapter")
err := wmi.QueryNamespace(query, &networkinfo, "root\\StandardCimv2")
它可以工作!
英文:
Thank @AlexandrKamenev!I'm sure I got the answer I wanted.Use the QueryNamespace() method to specify namespace:
Directly use QueryNamespace() method:
err := wmi.QueryNamespace("Select * from MSFT_PhysicalDisk", &diskMediaTypeInfo, "root\\Microsoft\\Windows\\Storage")
Use CreateQuery() with QueryNamespace() method
query := wmi.CreateQuery(&networkinfo, "WHERE Virtual=false", "MSFT_NetAdapter")
err := wmi.QueryNamespace(query, &networkinfo, "root\\StandardCimv2")
it works!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论