【Delphi】获取电脑唯一码(一机一码)

在日常开发中,可能需要获取每台设备的一个唯一码,那么如何获取每台设备的唯一码呢?一般的做法是获取系统唯一的序列号之类,比如硬盘序列号、CPU序列号、系统ID等等,因为每个电脑的序列号不一定一样(不排除有完全一样的,例如拷贝的虚拟机等),所以想要绝对的不一样也有一定的困难。

那么问题来了,如何获取诸如硬盘序列号、CPU序列号或者硬盘容量等呢?有多种方法,比如使用三方的控件,本文介绍的方法不适用第三方控件,直接使用windows的WMI框架来获取。

下面先介绍下WMI,然后提供一个通过WMI实现获取电脑唯一码的程序。

Windows Management Instrumentation(WMI,Windows 管理规范)是微软推出的一套用于管理 Windows 系统及应用程序的标准化接口和技术,基于分布式管理任务组(DMTF)的通用信息模型(CIM)标准,提供了统一的方式来查询、配置、监控和控制系统资源。

一、WMI 的核心组成

  1. CIM 对象管理器(CIMOM) WMI 的核心服务(winmgmt服务),负责处理 WMI 请求、管理 CIM 对象库(存储系统资源的元数据),并协调与底层系统的交互。

  2. **WMI 命名空间(Namespace)**用于组织和隔离管理对象的逻辑容器,类似文件系统的目录。常用命名空间:

    • root\cimv2:最常用,包含操作系统、硬件、软件等核心管理对象(如进程、服务、磁盘)。
    • root\subscription:用于 WMI 事件订阅(如监控进程创建、服务启动)。
    • root\securitycenter2:系统安全相关信息(如防火墙、 antivirus 状态)。
  3. WMI 类(Class) 描述可管理资源的模板,每个类对应一类系统资源(如Win32_Process对应进程,Win32_Service对应服务)。类包含属性 (资源的特征,如NameProcessId)和方法 (可执行的操作,如Create创建进程、StopService停止服务)。

  4. WQL 查询语言WMI 查询语言(WMI Query Language),语法类似 SQL,用于从 WMI 类中查询对象。例如:

    wql

    复制代码
    SELECT Name, ProcessId FROM Win32_Process WHERE Name = 'notepad.exe'

二、WMI 的核心功能

  1. 系统信息查询获取硬件(CPU、内存、磁盘、网络适配器)、软件(进程、服务、安装的程序)、操作系统(版本、启动时间、用户)等信息。

  2. 系统配置管理远程或本地修改系统设置,如启动 / 停止服务、创建 / 终止进程、修改注册表、配置网络适配器等。

  3. 事件监控与响应订阅系统事件(如进程创建、服务状态变化、磁盘空间不足),并触发自定义操作(如日志记录、自动修复)。

  4. 远程管理通过网络远程管理其他 Windows 设备(需权限配置),支持跨域、防火墙穿透(基于 DCOM 或 WS-Management 协议)。

三、WMI 的典型应用场景

1. 系统监控与诊断
  • 硬件监控 :查询 CPU 使用率(Win32_Processor.LoadPercentage)、内存占用(Win32_PhysicalMemory)、磁盘空间(Win32_LogicalDisk.FreeSpace)等,用于性能分析或告警。
  • 软件监控 :实时监控进程启动 / 退出(通过Win32_ProcessTrace事件类)、服务状态(Win32_Service.State),排查异常程序。
2. 批量管理与自动化
  • 企业级设备管理:通过脚本(PowerShell/VBScript)或工具批量查询域内所有计算机的硬件配置(如是否安装某型号显卡)、软件版本(如 Office 版本)。
  • 自动化运维 :编写脚本自动执行重复性任务,例如:
    • 停止所有名为 "testService" 的服务:Get-WmiObject Win32_Service -Filter "Name='testService'" | Invoke-WmiMethod -Name StopService(PowerShell)。
    • 远程在多台计算机上创建文件夹:调用Win32_FileSystemObjectCreateFolder方法。
3. 安全审计与日志
  • 进程审计 :记录所有新启动的进程(通过Win32_ProcessCreate事件),追踪可疑程序。
  • 权限检查 :查询用户组信息(Win32_Group)、登录会话(Win32_LogonSession),审计未授权访问。
4. 开发集成
  • 应用程序扩展:在 C++/C#/Delphi 等语言中调用 WMI 接口,让程序获取系统信息(如在安装程序中检查磁盘空间是否足够)。
  • 设备驱动管理 :查询即插即用设备(Win32_PnPEntity),开发硬件监控工具。

四、WMI 的使用工具与方式

  1. 命令行工具

    • wmic:Windows 命令行 WMI 客户端,支持直接执行 WQL 查询。例如:

      cmd

      复制代码
      wmic process where "name='notepad.exe'" get name, processid  # 查询记事本进程
      wmic service where "state='running'" get name, displayname   # 查询运行中的服务
    • PowerShell:更强大的 WMI 交互工具,通过Get-WmiObject(旧)或Get-CimInstance(新) cmdlet 操作。

  2. 脚本语言

    • VBScript:通过GetObject("winmgmts:")连接 WMI 服务,适合编写简单管理脚本。

    • PowerShell:原生支持 WMI/CIM,语法更简洁,例如: powershell

      复制代码
      # 获取所有物理磁盘大小
      Get-CimInstance -ClassName Win32_DiskDrive | Select-Object Model, Size
  3. 编程语言

    • C#:通过System.Management命名空间(如ManagementObjectSearcher类)调用 WMI。
    • Delphi:通过ISWbemLocatorISWbemServices等 COM 接口操作(如前文示例)。
    • C++:使用 WMI C API(如IWbemLocator接口)。
  4. 图形化工具

    • WMI Explorer:第三方工具,可视化浏览 WMI 命名空间、类、属性和方法,适合学习和调试。
    • 计算机管理 :Windows 自带工具(compmgmt.msc),通过 "WMI 控制" 管理 WMI 配置(如安全权限)。

五、WMI 的优缺点

  • 优点

    • 标准化:基于 CIM 标准,接口统一,无需针对不同硬件 / 软件编写专用代码。
    • 功能全面:覆盖系统管理的几乎所有场景(硬件、软件、事件、配置)。
    • 远程能力:支持跨网络管理,适合企业级批量操作。
  • 缺点

    • 复杂度高:类和属性繁多,初学者需花时间学习(可参考微软 WMI 类文档)。
    • 性能开销:复杂查询或大量对象遍历可能占用较多系统资源。
    • 安全风险:若配置不当,可能被恶意利用(如远程执行命令),需严格控制 WMI 权限。

六、总结

WMI 是 Windows 系统管理的核心技术,通过统一的接口和查询语言,实现了对系统资源的全方位管理。无论是日常运维、批量管理、应用程序开发还是安全审计,WMI 都能提供强大的支持。掌握 WMI 的使用,能显著提升 Windows 系统管理的效率和自动化水平。

七、Delphi 样例说明

Delphi 复制代码
function Get_Win32_Item_Value(Win32_ClassName,ItemName : string) : string;
var
  FSWbemLocator : OleVariant;
  FWMIService   : OleVariant;
  FWbemObjectSet: OleVariant;
  FWbemObject   : OleVariant;
  oEnum         : IEnumvariant;
  QueryStr      : string;
  iValue        : LongWord;
  OleValue      : OleVariant;
  i             : Integer;
begin
  //初始化数据
  if not VarIsClear(FSWbemLocator)  then FSWbemLocator := Null;
  if not VarIsClear(FWMIService)    then FWMIService := Null;
  if not VarIsClear(FWbemObjectSet) then FWbemObjectSet := Null;
  if not VarIsClear(FWbemObject)    then FWbemObject := Null;

  CoInitialize(nil);
  try
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService   := FSWbemLocator.ConnectServer('localhost','root\CIMV2','','');
    QueryStr      := 'SELECT ' + ItemName + ' FROM ' + Win32_ClassName;
    FWbemObjectSet:= FWMIService.ExecQuery(QueryStr,'WQL',0,Null);

    oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVARIANT;

    while oEnum.Next(1,FWbemObject,iValue) = S_OK do
      begin
        if iValue <> 1 then Break;
        OleValue := FWbemObject.Properties_.Item(ItemName);  //取得返回的属性值
        if VarIsNull(OleValue) then
           Result := 'NULL'
        else
        if VarIsArray(OleValue) then
           begin
             Result := '';
             for I := VarArrayLowBound(Result, 1) to VarArrayHighBound(Result, 1) do
               Result := Result + ' | ' + VarToStr(VarArrayGet(OleValue,[i]));
           end
        else
          begin
            Result := VarToStr(OleValue);
           if varType(OleValue) = varDispatch then   //日期型
              Result := Result.Substring(0,14);
          end;

        //只需要循环一次,直接退出
        Break;
      end;

  finally
   CoUninitialize;
  end;
end;

八、完整代码

EXE执行程序

EXE + 源代码

相关推荐
wuty0075 个月前
记录.Net 8 发布增加 PublishTrimmed 裁剪选项,调用WMI 的ManagementObject 异常
wmi·managementobject 异常·publishtrimmed 裁剪
斯内科10 个月前
C#使用WMI获取控制面板中安装的所有程序列表
开发语言·c#·wmi
得鹿梦鱼、2 年前
QT案例 使用WMI获取win_32类的属性值,包括Win32提供程序类中的属性
开发语言·c++·qt·windows api·wmi
pureman_mega2 年前
Windows Management Instrumentation (WMI) 的使用---一些系统接口的替代者
windows·wmi