gpt4 book ai didi

delphi - 如何使用delphi提高WMI性能?

转载 作者:行者123 更新时间:2023-12-03 14:37:29 25 4
gpt4 key购买 nike

我编写了一个简单的函数来使用 WMI 检索系统信息,并将类和属性名称作为参数传递。当我执行这样的函数时

  Writeln('Procesor Id '+GetWMIInfo('Win32_Processor','Name'));
Writeln('Mother Board Serial '+GetWMIInfo('Win32_BaseBoard','SerialNumber'));
Writeln('BIOS Version '+GetWMIInfo('Win32_BIOS','Version'));

执行时间约为1300毫秒。

我需要检索很多附加信息,那么是否可以减少该函数的执行时间?

这是一个具有以下功能的示例应用程序

{$APPTYPE CONSOLE}

uses
Diagnostics,
SysUtils,
ActiveX,
ComObj,
Variants;

function GetWMIInfo(const WMIClass, WMIProperty:string): string;
var
sWbemLocator : OLEVariant;
sWMIService : OLEVariant;
sWbemObjectSet: OLEVariant;
sWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
Result:='';
sWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
sWMIService := sWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
sWbemObjectSet:= sWMIService.ExecQuery('SELECT * FROM '+WMIClass,'WQL');
oEnum := IUnknown(sWbemObjectSet._NewEnum) as IEnumVariant;
if oEnum.Next(1, sWbemObject, iValue) = 0 then
Result:=sWbemObject.Properties_.Item(WMIProperty).Value;
end;

var
SW : TStopwatch;

begin
try
CoInitialize(nil);
try
SW.Reset;
SW.Start;
Writeln('Procesor Id '+GetWMIInfo('Win32_Processor','Name'));
Writeln('Mother Board Serial '+GetWMIInfo('Win32_BaseBoard','SerialNumber'));
Writeln('BIOS Version '+GetWMIInfo('Win32_BIOS','Version'));
SW.Stop;
Writeln('Elapsed ms '+FormatFloat('#,0.000',SW.Elapsed.TotalMilliseconds));
finally
CoUninitialize;
end;
except
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Readln;
end.

最佳答案

这些是提高 WMI 性能的一些技巧

1.) 重新利用对 CreateOleObject 的调用

2.) 重用 WMI 连接

更昂贵的任务之一是建立与 WMI 服务的连接,因此请重新利用该连接,而不是每次调用该函数时都创建一个连接。

3.) 仅检索您要使用的列

检索 WMI 的每个属性都有不同的来源,例如 Windows 注册表、WinAPi 等,限制列将提高性能。阅读这篇文章了解更多信息 How obtain the source of the WMI Data

4.) 使用WBEM_FLAG_FORWARD_ONLY当您执行 WQL 语句时标记。

按照上述提示,我重写了您的示例应用程序

{$APPTYPE CONSOLE}

uses
Diagnostics,
SysUtils,
ActiveX,
ComObj,
Variants;

var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;

function GetWMIInfo(const WMIClass, WMIProperty:string): string;
const
wbemFlagForwardOnly = $00000020;
var
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
Result:='';
FWbemObjectSet:= FWMIService.ExecQuery(Format('Select %s from %s',[WMIProperty, WMIClass]),'WQL',wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
if oEnum.Next(1, FWbemObject, iValue) = 0 then
Result:=FWbemObject.Properties_.Item(WMIProperty).Value;
end;

var
SW : TStopwatch;

begin
try
CoInitialize(nil);
try
SW.Reset;
SW.Start;
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
Writeln('Procesor Id '+GetWMIInfo('Win32_Processor','Name'));
Writeln('Mother Board Serial '+GetWMIInfo('Win32_BaseBoard','SerialNumber'));
Writeln('BIOS Version '+GetWMIInfo('Win32_BIOS','Version'));
SW.Stop;
Writeln('Elapsed ms '+FormatFloat('#,0.000',SW.Elapsed.TotalMilliseconds));
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Readln;
end.

执行时间从 1245 毫秒缩短到 180 毫秒(在我的笔记本电脑上)。

关于delphi - 如何使用delphi提高WMI性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10199531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com