从 Delphi 访问 WMI

Access the WMI from Delphi

虽然我了解如何连接到 WMI 并获取所需信息,但我不明白我们需要什么 while 循环 (while oEnum.Next(1, FWbemObject, iValue) = 0 do )?来自 How to get the installed video card ( Delphi) :

FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
FWbemObjectSet:= FWMIService.ExecQuery('SELECT Name,PNPDeviceID  FROM Win32_VideoController','WQL',wbemFlagForwardOnly);
oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while oEnum.Next(1, FWbemObject, iValue) = 0 do
begin
  Writeln(Format('Name           %s',[String(FWbemObject.Name)]));// String
  Writeln(Format('PNPDeviceID    %s',[String(FWbemObject.PNPDeviceID)]));//   String        
  Writeln;
  FWbemObject:=Unassigned;
end;

计算机可能有多个视频卡。这个循环只是遍历每个循环。

可能有不止一张显卡,因此循环。

oEnum 是一个 IENUMVARIANT and Next returns HResult 在这种情况下可以是:

S_OK    The number of elements returned is celt.
S_FALSE The number of elements returned is less than celt.

注:S_OK转化为0,S_FALSE转化为1。

通过_NewEnum 属性公开的SWbemServices.ExecQuery method returns a collection with the result of the WMI sentence. This object support iteration through the IEnumVARIANT

使用枚举器是遍历 returned 对象结果的唯一方法(某些语言如 vbscript 实现了一个隐藏的隐式枚举器,您可以访问此类信息使用 for..in 循环遍历 returned 对象)。在 Delphi 中,要访问此类枚举器,您必须将 returned 对象的 _NewEnum 属性 转换为 IEnumVariant 接口。

然后您可以使用 Next 方法迭代数据。这种方法的结果是这样记录的

  • S_OK元素个数returned为celt.
  • S_FALSE元素个数returned小于celt.

celt : 是第一个参数的名称,表示 Next 方法要检索的元素数。

在这种情况下,我们一次请求 1 个元素(检查 IEnumVARIANT.Next 函数的第一个参数)所以如果函数的 return 是 S_OK (0) 意味着其中函数 returned 成功地收集了 1 个元素。