代码之家  ›  专栏  ›  技术社区  ›  Sarah Weinberger

存储:C#相当于PowerShell命令

  •  3
  • Sarah Weinberger  · 技术社区  · 8 年前

    这个PowerShell命令的C#等价物是什么?

    PS C:\WINDOWS\system32> gwmi win32_DiskDrive | %{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_PnpEntity" | %{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)}"}} | fl __CLASS,__RELPATH
    

    ...
    __CLASS   : Win32_SystemDriver
    __RELPATH : Win32_SystemDriver.Name="disk"
    
    __CLASS   : Win32_ComputerSystem
    __RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH"
    
    __CLASS   : Win32_IDEController
    __RELPATH : Win32_IDEController.DeviceID="PCI\\VEN_8086&DEV_8C82&SUBSYS_79171462&REV_00\\3&11583659&0&FA"
    
    __CLASS   : CIM_DataFile
    __RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys"
    
    __CLASS   : Win32_DiskDrive
    __RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE1"
    
    
    __CLASS   : Win32_SCSIController
    __RELPATH : Win32_SCSIController.DeviceID="PCI\\VEN_144D&DEV_A804&SUBSYS_A801144D&REV_00\\6&381D8F6A&0&00080008"
    
    __CLASS   : Win32_SystemDriver
    __RELPATH : Win32_SystemDriver.Name="disk"
    
    __CLASS   : Win32_ComputerSystem
    __RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH"
    
    __CLASS   : CIM_DataFile
    __RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys"
    
    __CLASS   : Win32_DiskDrive
    __RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE2"
    ...
    

    我想我不明白的是PowerShell命令是如何运行的。我确实知道部分译文。

                ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
    
    foreach (ManagementObject wmi_HD in searcher.Get())
    {
        String driveDeviceId = wmi_HD["DeviceID"].ToString();
    }
    

    gwmi win32_DiskDrive

    我有另一个代码片段,在那里我得到了与物理磁盘相关的驱动器号,它使用 ASSOCIATORS OF gwmi查询。因此,答案应类似于:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Management;
    
    String query2 = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
    foreach (ManagementObject partition in new ManagementObjectSearcher(query2).Get())
    {
        foreach (ManagementObject disk in new ManagementObjectSearcher(
                    "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='"
                        + partition["DeviceID"]
                        + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
        {
            String diskMount = disk["Name"].ToString();
        }
    }
    

    | 只是一个嵌入式for循环,其中内部wmi查询将使用另一个循环元素的结果。我想要的查询有两个 并使用了一组 {$($_.__RELPATH)} .

    1 回复  |  直到 8 年前
        1
  •  6
  •   Sarah Weinberger    8 年前

    笔记 1: 我挣扎了很长时间,做了研究,最终对事情有了更好的理解。我能够自己构造问题的答案。我把答案和解释放在这里,希望能教育其他人。至少对我来说,WMI很难理解,尤其是在复杂的情况下。

    1. 最后的更新很棒,请查看。

    我的重大突破来自于信不信由你 this Microsoft网页以及来自的帮助 ScryptingGuy this 所以这篇文章是关于在WMI查询过滤器中转义美元符号的。

    String propDiskRelpaths = wmiDisks["__RELPATH"].ToString();
    

    我发现大括号是WMI所必需的,并指示一个值。美元符号仅表示外部查询的结果。内涵 ($_.__RELPATH) 是表示上一个查询的_urelpath属性的奇特方式。

    查询首先枚举系统上的所有磁盘。然后,第二个查询枚举磁盘的所有PNP实体(只有一个),而最后一个查询获取磁盘的所有路径关联(驱动程序层次结构)。每个查询向下钻取一个级别。

    PS C:\WINDOWS\system32> gwmi win32_DiskDrive | fl __CLASS,__RELPATH
    
    ....
    __CLASS   : Win32_DiskDrive
    __RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE3"
    

    这是第二个命令,它为磁盘生成PNP实体。在本例中,我选择了我的C:drive,drive 0,而不是我的M.2卡drive 3作为示例。真正的代码在for循环中,所以我会得到所有的驱动器。

    PS C:\WINDOWS\system32> gwmi -query 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"} where resultclass = Win32_PnpEntity' | fl __CLASS,__RELPATH
    
    __CLASS   : Win32_PnPEntity
    __RELPATH : Win32_PnPEntity.DeviceID="SCSI\\DISK&VEN_NVME&PROD_SAMSUNG_SSD_960\\7&335357E&0&000000"
    

    最后一个命令和输出是:

    PS C:\WINDOWS\system32> gwmi -query 'ASSOCIATORS OF {Win32_PnPEntity.DeviceID="SCSI\\DISK&VEN_NVME&PROD_SAMSUNG_SSD_960\\7&335357E&0&000000"}' | fl __CLASS,__RELPATH
    
    
    __CLASS   : Win32_SCSIController
    __RELPATH : Win32_SCSIController.DeviceID="PCI\\VEN_144D&DEV_A804&SUBSYS_A801144D&REV_00\\6&381D8F6A&0&00080008"
    
    __CLASS   : Win32_SystemDriver
    __RELPATH : Win32_SystemDriver.Name="disk"
    
    __CLASS   : Win32_ComputerSystem
    __RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH"
    
    __CLASS   : CIM_DataFile
    __RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys"
    
    __CLASS   : Win32_DiskDrive
    __RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"
    

    正如你所见,我的M.2卡被列为SCSI设备,而不是真正的NVMe PCIe卡。我做了研究,这是意料之中的,因为微软 StorNVMe.sys 驱动程序将NVMe实现为 IOCTL_SCSI_* IOCTL_NVME_*

    PS C:\WINDOWS\system32>gwmi-查询{Win32\u PnPEntity.DeviceID=“SCSI\\DISK&venu NVME&PROD\u SAMSUNG\u SSD\u 960\\7&335357E&0&000000”}的关联器| fl _u类,uu RELPATH
    
    
    __类:Win32_SCSIController
    
    __类:Win32_SystemDriver
    
    __类别:Win32_ComputerSystem
    __RELPATH:Win32_ComputerSystem.Name=“JMR-ENG-SARAH”
    
    __RELPATH:CIM\u DataFile.Name=“c:\\windows\\system32\\drivers\\disk.sys”
    
    __RELPATH:Win32\u DiskDrive.DeviceID=“\\\.\\物理驱动器0”
    

    希望这个解释是清楚的。如果需要更多解释,请告诉我。哦,下面的代码假设VS2017或更高版本。

    using System;
    using System.Collections.Generic;
    using System.Management;
    using SiloStor.Tools;
    
    internal static void EnumerateClassPaths()
    {
        try
        {
            // Enumerate all disk drives.
            ManagementObjectSearcher oSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
            foreach (ManagementObject wmiDisks in oSearcher.Get())
            {
                // Get the properties needed.
                String propDiskRelpaths = wmiDisks["__RELPATH"].ToString();
    
                // 
                String wmiQuery1 = "ASSOCIATORS OF {" + propDiskRelpaths + "} WHERE ResultClass = Win32_PnpEntity";
                foreach (ManagementObject wmiPnp in new ManagementObjectSearcher(wmiQuery1).Get())
                {
                    // Get the properties needed.
                    String propPnpRelpaths = wmiPnp["__RELPATH"].ToString();
    
                    // 
                    String wmiQuery2 = "ASSOCIATORS OF {" + propPnpRelpaths + "}";
                    foreach (ManagementObject wmiDrivers in new ManagementObjectSearcher(wmiQuery2).Get())
                    {
                        String driverClass = wmiDrivers["__CLASS"].ToString();
                        String driverRelpath = wmiDrivers["__RELPATH"].ToString();
                        Console.WriteLine($"__CLASS   : {driverClass}");
                        Console.WriteLine($"__RELPATH : {driverRelpath}");
                        Console.WriteLine("");
                    }
                }
            }
        }
    
        catch (Exception ex)
        {
            // Log the error.
            Errors.LogError(ex);
        }
    }
    

    更新:

    link WMI Code Creator 我没有收到微软的付款,我也不认为这个工具是WMI工作的“必备品”,但它实际上相当不错,根本没有广告。

    这个 ,为应用程序提供源代码,为WMI查询生成C#和VB.Net源代码。遗憾的是,WMI查询仅限于基本命令,但仍然非常有用。另一个有用的地方是,该工具显示了用户可以查询的类,这也非常有用。可悲的是,没有 ASSOCIATORS OF 或串联查询,但确实有许多其他有用的功能。看看吧,希望能有所帮助。