【WMI定义】
WMI,是Windows 2K/XP管理系统的核心;对于其他的Win32操作系统,WMI是一个有用的插件。WMI以CIMOM为基础,CIMOM即公共信息模型对象管理器(Common Information Model Object Manager),是一个描述操作系统构成单元的对象数据库,为MMC和脚本程序提供了一个访问操作系统构成单元的公共接口。有了WMI,工具软件和脚本程序访问操作系统的不同部分时不需要使用不同的API;相反,操作系统的不同部分都可以插入WMI,如图所示,工具软件和脚本程序可以方便地读写WMI
【DELPHI操作WMI】
在DELPHI中利用WMI获取系统的参数或信息是非常方便的一种方式,使用起来比API更简单,通常我们只需写一个或几个公共函数,再根据不同的需求进行传参即可获得想要信息,而公共的函数写法如下:
function GetWMIProperty(WMIType, WMIProperty:AnsiString):String;
var
Wmi, Objs, Obj: oleVariant;
Enum: IEnumVariant;
C: Cardinal;
begin
Wmi:= CreateOleObject('WbemScripting.SWbemLocator');
Objs := Wmi.ConnectServer('.','root/cimv2').ExecQuery('Select * from Win32_' + WMIType);
Enum := IEnumVariant(IUnknown(Objs._NewEnum));
Enum.Reset;
Enum.Next(1,Obj,C);
Obj := Obj.Properties_.Item(WMIProperty, 0).Value;
if VarIsNull(obj) then
begin
Result:='Error';
end;
if VarIsArray(obj) then
begin
Result := Obj[0];
end;
if VarIsStr(obj) or VarIsCustom(obj) or VarIsFloat(obj) or VarIsNumeric(obj) or VarIsOrdinal(obj) then
begin
Result:= Obj;
end;
end;
在以上的公共函数中,调用时需要传入两个参数:
WMIType:WMI的库名,在下面我会将WMI所有库名全部发出
WMIProperty:具体的参数名称
如:我需要获取计算机名称,则调用 Win32_OperatingSystem库中的CSName参数即可,假如我们想把计算机名显示在一个MEMO中,调用方式如下:
Memo1.Lines.Add('计算机名称: '+GetWMIProperty('OperatingSystem','CSName'));
以上的公共函数只要是字符串类的参数,都可直接使用,调用方式也如上所示,如:
Memo1.Lines.Add('系统序列号: '+GetWMIProperty('OperatingSystem','SerialNumber'));
Memo1.Lines.Add('系统内存: '+FormatFloat('0',StrToFloat(GetWMIProperty('OperatingSystem','TotalVisibleMemorySize'))/1000) + 'MB');
Memo1.Lines.Add('硬件制造商: '+GetWMIProperty('Bios','Manufacturer'));
Memo1.Lines.Add('出厂日期: '+GetWMIProperty('Bios','ReleaseDate'));
Memo1.Lines.Add('适配器的类型: '+GetWMIProperty('NetworkAdapter','Name'));
而有时我们的电脑会具备多个硬件,如双CPU,双硬盘,双显卡,双内存条等等,那么如果想要获得全部的信息,我们需要进行循环查询,如:电脑上有两个显卡,我们想获得所有显卡的参数,那么就需要按如下方式实现:
首先:写一个获得显卡参数的函数,而这个函数必须要传入显卡名称的参数到函数中
以下代码传参说明:
WMIType:WMI库名称
WMIProperty:想获得的参数名称
WMISearch:where 后面搜索的参数类型
WMISearchText:String:where后面搜索的值
function GetWMISub(WMIType,WMIProperty,WMISearch,WMISearchText:String):String;
var
Wmi, Objs, Obj: oleVariant;
Enum: IEnumVariant;
C: Cardinal;
begin
Wmi:= CreateOleObject('WbemScripting.SWbemLocator');
Objs := Wmi.ConnectServer('.','root/cimv2').ExecQuery('Select * from Win32_' + WMIType + ' where '+WMISearch+' = '+ '"'+WMISearchText+'"');
Enum := IEnumVariant(IUnknown(Objs._NewEnum));
Enum.Reset;
Enum.Next(1,Obj,C);
Obj := Obj.Properties_.Item(WMIProperty, 0).Value;
if VarIsNull(obj) then
begin
Result:='Unknow';
end;
if VarIsArray(obj) then
begin
Result := Obj[0];
end;
if VarIsStr(obj) or VarIsCustom(obj) or VarIsFloat(obj) or VarIsNumeric(obj) or VarIsOrdinal(obj) then
begin
Result:= Obj;
end;
end;
以上是获取单个硬件参数的公共函数,如果有多个硬件时,我们必须在循环查找中,调用上面的函数
procedure TFrmMain.RzGroup1Items4Click(Sender: TObject);
var
CpuArc,INum:string;
i:Integer;
Wmi, Objs, Obj: oleVariant;
Enum: IEnumVariant;
C: Cardinal;
Str,str1:string;
begin
Memo1.Clear;
Memo1.Lines.Add('【显示参数信息】');
Wmi:= CreateOleObject('WbemScripting.SWbemLocator');
Objs := Wmi.ConnectServer('.','root/cimv2').ExecQuery('Select * from Win32_VideoController');
Enum := IEnumVariant(IUnknown(Objs._NewEnum));
Enum.Reset;
while (Enum.Next(1,Obj,C)=s_ok) do //此处建立循环查询
begin
str1:='DeviceID';
Obj := Obj.Properties_.Item(str1, 0).Value;
if VarIsNull(obj) then
begin
Str:='ERROR';
end;
if VarIsArray(obj) then
begin
str:=Obj[0];
end;
if VarIsStr(obj) or VarIsCustom(obj) or VarIsFloat(obj) or VarIsNumeric(obj) or VarIsOrdinal(obj) then
begin
str:=Obj;
end;
//以下是调用上面的公共函数
Memo1.Lines.Add('');
Memo1.Lines.Add('显卡名称: '+GetWMISub('VideoController','Name',str1,Str));
Memo1.Lines.Add('装置识别符: '+GetWMISub('VideoController','PNPDeviceID',str1,Str));
Memo1.Lines.Add('显存大小: '+FormatFloat('0',StrToFloat(GetWMISub('VideoController','AdapterRAM',str1,Str))/1024/1024/1024)+' GB');
Memo1.Lines.Add('驱动版本: '+GetWMISub('VideoController','DriverVersion',str1,Str));
Memo1.Lines.Add('当前分辨率: '+GetWMISub('VideoController','CurrentHorizontalResolution',str1,Str)+' X '+GetWMISub('VideoController','CurrentVerticalResolution',str1,Str));
Memo1.Lines.Add('芯片的标识符: '+GetWMISub('VideoController','AdapterDACType',str1,Str));
Memo1.Lines.Add('单像素比特数: '+GetWMISub('VideoController','CurrentBitsPerPixel',str1,Str));
Memo1.Lines.Add('当前刷新频率: '+GetWMISub('VideoController','CurrentRefreshRate',str1,Str)+' Hz');
end;
end;
通过上面的公共函数再配合循环查询,我们即可获得所有的显卡参数参数,如下图
当然,今天本章节只是对WMI做个简单的介绍,后面我会单独针对WMI每一个库的参数进行说明,下面先把WMI所有库名写上,让大家有个简单的概念
WMI类库名称,WIN32开头的有:
Win32_Account
Win32_ActiveRoute
Win32_AutochkSetting
Win32_BaseBoard
Win32_BaseService
Win32_BIOS
Win32_BootConfiguration
Win32_Bus
Win32_ComputerSystem
Win32_ComputerSystemWindowsProductActivation
Win32_Desktop
Win32_DesktopMonitor
Win32_DeviceSettings
Win32_DiskDrive
Win32_DiskDrivePhysicalMedia
Win32_DisplayConfiguration
Win32_Environment
Win32_FontIntoAction
Win32_Group
Win32_IDEController
Win32_IP4PersistedRouteTable
Win32_IP4RouteTable
Win32_Keyboard
Win32_LogicalDisk
Win32_LogicalProgramGroup
Win32_LogonSession
Win32_MappedLogicalDisk
Win32_MemoryDevice
Win32_MotherboardDevice
Win32_NetworkAdapter
Win32_NetworkAdapterConfiguration
Win32_NetworkAdapterSetting
Win32_NetworkClient
Win32_NetworkConnection
Win32_OperatingSystem
Win32_PerfFormattedData_RemoteAccess_RASPort
Win32_PerfFormattedData_RemoteAccess_RASTotal
Win32_PerfRawData_RemoteAccess_RASPort
Win32_PhysicalMedia
Win32_PhysicalMemory
Win32_PNPDevice
Win32_PortConnector
Win32_POTSModem
Win32_POTSModemToSerialPort
Win32_Printer
Win32_PrinterConfiguration
Win32_Process
Win32_Processor
Win32_Product
Win32_ProgramGroup
Win32_ScheduledJob
Win32_SerialPort
Win32_SerialPortConfiguration
Win32_SerialPortSetting
Win32_Service
Win32_ServiceControl
Win32_SoundDevice
Win32_StartupCommand
Win32_SystemAccount
Win32_SystemBIOS
Win32_SystemSetting
Win32_SystemTimeZone
Win32_SystemUsers
Win32_TapeDrive
Win32_TemperatureProbe
Win32_USBController
Win32_USBControllerDevice
Win32_UserAccount
Win32_VideoController
Win32_VideoSettings
Win32_WindowsProductActivation