C#使用访问WMI的接口获取计算机硬件和操作系统信息,WMI代码生成器介绍【ManagementObjectSearcher、ManagementClass】

简介: ManagementObjectSearcher 用于获取基于指定查询的管理对象集合。是获取管理信息最常用的入口点。例如,可以遍历所有的硬盘驱动、网络适配器、进程和系统上的其他管理对象,或者...

ManagementObjectSearcher

ManagementObjectSearcher类

ManagementObjectSearcher 用于获取基于指定查询的管理对象集合。是获取管理信息最常用的入口点。

例如,可以遍历所有的硬盘驱动、网络适配器、进程和系统上的其他管理对象,或者查询所有的正在使用、服务停止等的网络连接(query for all network connections that are up, services that are paused, and so on)。

其查询主要使用的是WMI查询,以及可选的ManagementScope,当调用Get()方法时才会执行对应的查询,返回一个管理对象集合(a collection of management objects)。

ManagementObjectSearcher 类在System.Management命名空间下。

Environment类也可以获取一些简单的系统信息,比如: Environment.MachineName获得计算机名, Environment.UserName获得操作系统登录用户名, Environment.Is64BitOperatingSystem是否是64位操作系统, Environment.ProcessorCount当前系统的处理器数, Environment.NewLine当前环境的换行符等。

WMI —— Windows Management Instrumentation

WMI是用来获取Windows系统信息(软硬件、网络等)的技术,并提供可供vbspowershell.NET/C# 等各种工具或编程语言使用的接口。

WMI底层是基于COM的。同时WMI在性能上并不是很好。

WMI目前已经不推荐使用,其最新版本(或替代品)为Windows Management Infrastructure(MI),它与WMI完全兼容,使用WMI方式可以访问MI,现代编程更推荐直接使用MI。

Why Use MI?介绍到,MI使用新的本地API和.NET API(不再需要使用复杂的COM代码与WMI交互),SDK开箱即用,减少开发时间;与PowerShell紧密集成;基于最新的标准。

其具体使用可直接参见官方文档。How to Implement a Managed MI Client

获取常用系统和硬件信息

使用可以访问WMI的ManagementObjectSearcher对象,可以获取很多需要的计算机的硬件或操作系统的信息。

使用步骤

  1. 添加引用:System.Management
  2. 引入命名空间:using System.Management;
  3. 创建 ManagementObjectSearcher 对象,执行查询语句和可选的一些参数。

比如 var searcher = new ManagementObjectSearcher("select * from " + Key);

其中的key为WMI提供的API类,其常用列表见后续

  1. 调用 searcher.Get() 执行查询,获得 ManagementObjectCollection 集合
  2. 遍历 ManagementObjectCollection 集合获得 ManagementObject
  3. 通过 managementObject[name]ManagementObject.GetPropertyValue(name) 获得想要的属性值。

若不知道name,可以先遍历打印一下:

foreach (var property in managementObject.Properties)
{
    Console.WriteLine(property.Name+":"+property.Value);
}

使用实例(ManagementObjectSearcher查询获取)

获取CPU序列号

//获取CPU序列号
public string[] GetCPUSerialNumber()
{
   var cpuSerialNumbers = new List<string>();

   using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Processor"))
   {
       var moCollects = searcher.Get();
       foreach (ManagementObject mo in moCollects)
       {
           cpuSerialNumbers.Add(mo["ProcessorId"].ToString().Trim());
       }
       return cpuSerialNumbers.ToArray(); 
   }
}

获取主板序列号

BIOS的 serialnumber有的时候无法获取,会返回 Not Applicable
//获取主板序列号
public string GetBIOSSerialNumber()
{
   using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_BIOS"))
   {
       string sBIOSSerialNumber = "";

       foreach (ManagementObject mo in searcher.Get())
       {
           sBIOSSerialNumber = mo.GetPropertyValue("SerialNumber").ToString().Trim();
           break;
       }
       return sBIOSSerialNumber; 
   }
}

获取硬盘序列号

//获取硬盘序列号
public string[] GetHardDiskSerialNumber()
{
      var diskSerialNumbers = new List<string>();
      using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia"))
      {
          foreach (ManagementObject mo in searcher.Get())
          {
              diskSerialNumbers.Add(mo["SerialNumber"].ToString().Trim());
          }
          return diskSerialNumbers.ToArray(); 
      }
}

获取网卡地址

可根据需要再排除虚拟机相关网卡。

/// <summary>
/// 获取网卡地址
/// </summary>
/// <returns></returns>
public string[] GetNetCardMACAddress()
{
      using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter WHERE ((MACAddress Is Not NULL) AND (Manufacturer <> 'Microsoft'))"))
      {
          var macSerialNumbers = new List<string>();


          foreach (ManagementObject mo in searcher.Get())
          {
              macSerialNumbers.Add(mo["MACAddress"].ToString().Trim());
          }
          return macSerialNumbers.ToArray();
      }
}

获取串口信息

/// <summary>
/// 获得串口信息。获取的不准确,比如会获取到蓝牙设备
/// </summary>
/// <returns></returns>
public static string[] GetComInfo()
{
   List<string> Comstrs = new List<string>();
   using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_PnPEntity"))
   {
       var hardInfos = searcher.Get();
       foreach (var comInfo in hardInfos)
       {
           var nameValue = comInfo.Properties["Name"].Value;
           if (nameValue != null && nameValue.ToString().Contains("COM")) // 是否需要.ToUpper()?
           {
               try
               {
                   //通讯端口(COM1) 转变为 COM1:通讯端口
                   string com = nameValue.ToString();
                   string[] strcom = com.Split(new char[2] { '(', ')' });

                   Comstrs.Add(strcom[1] + ":" + strcom[0]);
               }
               catch { }

               }
       }
       searcher.Dispose();
   }
   return Comstrs.ToArray();
}

获取一个进程的父进程

/// <summary>
/// 获取父进程。如果出错可能返回null
/// </summary>
/// <param name="process"></param>
/// <returns></returns>
public static Process GetParent(this Process process)
{
   try
   {
       //using (var query = new ManagementObjectSearcher("SELECT * FROM Win32_Process WHERE ProcessId=" + process.Id))
       using (var query = new ManagementObjectSearcher("root\\CIMV2", "SELECT ParentProcessId FROM Win32_Process WHERE ProcessId=" + process.Id))
       {
           return query
             .Get()
             .OfType<ManagementObject>()
             .Select(p => Process.GetProcessById((int)(uint)p["ParentProcessId"]))
             .FirstOrDefault();
       }
   }
   catch
   {
       return null;
   }
}

/// <summary>
/// 获取一个进程的父进程Id
/// </summary>
/// <param name="processId"></param>
/// <returns></returns>
public static int ParentProcessId(int processId)
{
   try
   {
       using (var query = new ManagementObjectSearcher("root\\CIMV2", "SELECT ParentProcessId FROM Win32_Process WHERE ProcessId=" + processId))
       {
           return query
             .Get()
             .OfType<ManagementObject>()
             .Select(p =>(int)(uint)p["ParentProcessId"])
             .FirstOrDefault();
       }
   }
   catch
   {
       return 0;
   }
}

使用实例(ManagementClass对象方法)

/// <summary>
/// 获取所有的进程
/// </summary>
/// <param name="tb"></param>
public static string ListAllProcesses()
{
   // list out all processes and write them into a stringbuilder
   using (ManagementClass MgmtClass = new ManagementClass("Win32_Process"))
   {
       StringBuilder sb = new StringBuilder();
       foreach (ManagementObject mo in MgmtClass.GetInstances())
       {
           sb.Append("Name:\t" + mo["Name"] + Environment.NewLine);
           sb.Append("ID:\t" + mo["ProcessId"] + Environment.NewLine);
           sb.Append(Environment.NewLine);
       }
       return sb.ToString();
   }
}

WMI代码生成器介绍(生成C#、VB、VB.Net代码)

WMI Code creator是微软官方提供的一个生成C#、VB、VB.Net使用WMI代码的工具。

通过它,可以很方便的生成需要的代码,而不用查找需要用到哪些WMI类、去哪找对应的类、属性又是哪些等各种烦人的问题。

点击进入直接下载。

或者从 InvaderZim85/WmiCodeCreator下载一个非官方的比较新的版本。

如下,查询BIOS

使用WMI Code creator可以执行如下操作:

  • 查询WMI命名空间
  • 执行方法
  • 接收事件通知
  • 浏览WMI命名空间。

通过选择Target Computer,可以生成本地计算机、远程计算机的代码。

附:常见的WMI的API类

ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + Key)查询中常见的key值。

硬件

  • Win32_Processor —— CPU 处理器
  • Win32_PhysicalMemory —— 物理内存条
  • Win32_Keyboard —— 键盘
  • Win32_PointingDevice —— 点输入设备,包括鼠标。
  • Win32_FloppyDrive —— 软盘驱动器
  • Win32_DiskDrive —— 硬盘驱动器
  • Win32_CDROMDrive —— 光盘驱动器
  • Win32_BaseBoard —— 主板
  • Win32_BIOS —— BIOS 芯片
  • Win32_ParallelPort —— 并口
  • Win32_SerialPort —— 串口
  • Win32_SerialPortConfiguration —— 串口配置
  • Win32_SoundDevice —— 多媒体设置,一般指声卡。
  • Win32_SystemSlot —— 主板插槽 (ISA & PCI & AGP)
  • Win32_USBController —— USB 控制器
  • Win32_NetworkAdapter —— 网络适配器
  • Win32_NetworkAdapterConfiguration —— 网络适配器设置
  • Win32_Printer —— 打印机
  • Win32_PrinterConfiguration —— 打印机设置
  • Win32_PrintJob —— 打印机任务
  • Win32_TCPIPPrinterPort —— 打印机端口
  • Win32_POTSModem —— MODEM
  • Win32_POTSModemToSerialPort —— MODEM 端口
  • Win32_DesktopMonitor —— 显示器
  • Win32_DisplayConfiguration —— 显卡
  • Win32_DisplayControllerConfiguration —— 显卡设置
  • Win32_VideoController —— 显卡细节。
  • Win32_VideoSettings —— 显卡支持的显示模式。

操作系统

  • Win32_TimeZone —— 时区
  • Win32_SystemDriver —— 驱动程序
  • Win32_DiskPartition —— 磁盘分区
  • Win32_LogicalDisk —— 逻辑磁盘
  • Win32_LogicalDiskToPartition —— 逻辑磁盘所在分区及始末位置。
  • Win32_LogicalMemoryConfiguration —— 逻辑内存配置
  • Win32_PageFile —— 系统页文件信息
  • Win32_PageFileSetting —— 页文件设置
  • Win32_BootConfiguration —— 系统启动配置
  • Win32_ComputerSystem —— 计算机信息简要
  • Win32_OperatingSystem —— 操作系统信息
  • Win32_StartupCommand —— 系统自动启动程序
  • Win32_Service —— 系统安装的服务
  • Win32_Group —— 系统管理组
  • Win32_GroupUser —— 系统组帐号
  • Win32_UserAccount —— 用户帐号
  • Win32_Process —— 系统进程
  • Win32_Thread —— 系统线程
  • Win32_Share —— 共享
  • Win32_NetworkClient —— 已安装的网络客户端
  • Win32_NetworkProtocol —— 已安装的网络协议
  • Win32_PnPEntity —— all device

参考

相关文章
|
22天前
|
存储 安全 固态存储
计算机启动:从插上电源到操作系统启动的全过程
当我们插上电源,计算机从休眠状态苏醒,直至操作系统完全启动,这一系列复杂的过程涉及到硬件和软件的多个层面。本文将详细解析计算机插上电源后操作系统所做的工作,揭示这一过程的技术细节。
35 6
|
1月前
|
安全 Linux 网络安全
nmap 是一款强大的开源网络扫描工具,能检测目标的开放端口、服务类型和操作系统等信息
nmap 是一款强大的开源网络扫描工具,能检测目标的开放端口、服务类型和操作系统等信息。本文分三部分介绍 nmap:基本原理、使用方法及技巧、实际应用及案例分析。通过学习 nmap,您可以更好地了解网络拓扑和安全状况,提升网络安全管理和渗透测试能力。
121 5
|
1月前
|
Web App开发 API Windows
取接口访问者信息[IP,浏览器,操作系统]免费API接口教程
此API用于获取访问者的IP地址、浏览器和操作系统信息,支持70多种浏览器和操作系统。通过POST或GET请求至`https://cn.apihz.cn/api/ip/getapi.php`,需提供用户ID和KEY。返回结果包括状态码、消息、IP、浏览器和操作系统信息。示例:{&quot;code&quot;:200,&quot;ip&quot;:&quot;175.154.88.178&quot;,&quot;browser&quot;:&quot;Chrome&quot;,&quot;os&quot;:&quot;Windows 10&quot;}。详情见官网文档。
|
3月前
|
人工智能 运维 安全
专访浪潮信息:AI 原生时代,浪潮信息引领服务器操作系统创新 全面贡献龙蜥社区
分享了关于 AI 原生化趋势下服务器操作系统进化的思考,以及浪潮信息在龙蜥社区开源贡献的思路、成果与未来技术发展规划。
专访浪潮信息:AI 原生时代,浪潮信息引领服务器操作系统创新 全面贡献龙蜥社区
|
3月前
|
SQL 存储 关系型数据库
C#一分钟浅谈:使用 ADO.NET 进行数据库访问
【9月更文挑战第3天】在.NET开发中,与数据库交互至关重要。ADO.NET是Microsoft提供的用于访问关系型数据库的类库,包含连接数据库、执行SQL命令等功能。本文从基础入手,介绍如何使用ADO.NET进行数据库访问,并提供示例代码,同时讨论常见问题及其解决方案,如连接字符串错误、SQL注入风险和资源泄露等,帮助开发者更好地利用ADO.NET提升应用的安全性和稳定性。
343 6
|
4月前
|
存储 算法 网络协议
了解操作系统的基本原理和常见操作,提高计算机使用效率
了解操作系统的基本原理和常见操作,提高计算机使用效率
57 4
|
4月前
|
运维 安全 Linux
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
|
4月前
|
缓存 NoSQL Redis
【Azure Redis 缓存】C#程序是否有对应的方式来优化并缩短由于 Redis 维护造成的不可访问的时间
【Azure Redis 缓存】C#程序是否有对应的方式来优化并缩短由于 Redis 维护造成的不可访问的时间
|
4月前
|
边缘计算 运维 安全
操作系统新浪潮问题之浪潮信息在标准制定方面的成果内容如何解决
操作系统新浪潮问题之浪潮信息在标准制定方面的成果内容如何解决
25 0
|
4月前
|
Linux 编译器 云计算
操作系统新浪潮问题之浪潮信息深入参与龙蜥社区并推出商业发行版操作系统的原因如何解决
操作系统新浪潮问题之浪潮信息深入参与龙蜥社区并推出商业发行版操作系统的原因如何解决
40 0