Ответ 1
Вот некоторые советы по улучшению производительности WMI
1.) Повторно вызовите вызов CreateOleObject
2.) Повторное использование соединения WMI
Одной из более дорогих задач является подключение к WMI-сервисам, поэтому повторно подключайте это соединение вместо создания одного соединения каждый раз, когда вы вызываете функцию.
3.) Получить только те столбцы, которые вы хотите использовать
Каждое свойство, которое извлекает WMI, имеет разные источники, такие как реестр Windows, WinAPi и т.д., ограничение столбцов улучшит производительность. прочитайте эту статью для получения дополнительной информации How obtain the source of the WMI Data
4.) При выполнении предложения WQL используйте флаг WBEM_FLAG_FORWARD_ONLY.
Следуя приведенным выше советам, я переписал ваше примерное приложение
{$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 мс (на моем ноутбуке).