【发布时间】:2023-03-12 07:20:01
【问题描述】:
目前我正在使用此功能。它工作正常,但每个查询大约需要 1 秒。所以在我的情况下,我在我的应用程序中浪费了 3 秒。目前我正在考虑使用 3 个线程在一秒钟内获取所有信息。
function GetWMIstring (wmiHost, wmiClass, wmiProperty : string):string;
var // These are all needed for the WMI querying process
Locator: ISWbemLocator;
Services: ISWbemServices;
SObject: ISWbemObject;
ObjSet: ISWbemObjectSet;
SProp: ISWbemProperty;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OleVariant;
SN: string;
begin
Result := '';
try
Locator := CoSWbemLocator.Create; // Create the Location object
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost, 'root\cimv2', '', '', '','', 0, nil);
ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass, 'WQL',
wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
Enum := (ObjSet._NewEnum) as IEnumVariant;
while Enum.Next(1, TempObj, Value) = S_OK do
begin
try SObject := IUnknown(TempObj) as ISWBemObject; except SObject := nil; end;
TempObj := Unassigned; // Always need to free interface in TempObj
if SObject <> nil then
begin
SProp := SObject.Properties_.Item(wmiProperty, 0);
SN := SProp.Get_Value;
if not VarIsNull(SN) then
begin
Result := SN;
Break;
end;
end;
end;
except // Trap any exceptions (Not having WMI installed will cause one!)
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
CoInitializeEx(nil,COINIT_MULTITHREADED) ; //required !!! Otherwise "EOleSysError: CoInitialize has not been called" occurs (Microsoft recommends CoInitializeEx instead of CoInitialize)
CPU_PROCESSOR_COUNT := StrToInt( getWMIstring('','Win32_ComputerSystem','NumberOfProcessors') ); // number of cpu on mainboard
CPU_PHYSICAL_CORES := StrToInt( getWMIstring('','Win32_Processor','NumberOfCores') ); // number of phisical cores
CPU_LOGICAL_CORES := StrToInt( getWMIstring('','Win32_Processor','NumberOfLogicalProcessors') ); //number of logical cores
CoUninitialize; //required !!!
end;
【问题讨论】:
-
添加更多线程是错误的解决方案。请改用
GetLogicalProcessorInformation或GetLogicalProcessorInformationEx。此外,您对CoInitializeEx的呼叫非常可疑。默认情况下,VCL 应用程序在主线程中初始化 COM。你做了什么来打破它。此外,您不能只初始化 COM,并在线程生命周期中的任意时间点完成它。这势必会引起冲突。无论如何,一旦您删除了 WMI,您就不必担心这一点,但您似乎在其他地方破坏了 COM 初始化。 -
我会使用this
-
@DavidHeffernan 从上下文中我猜想 OP 正在从线程执行
Button1Click(因此出现 COM 异常)。当然,这绝对不是正确的处理方式。 -
@J... 很难想象会是这样。框架在主线程中触发按钮点击
-
@DavidHeffernan:我在哪里建议 WMI? RRUZ 的 uSMBIOS 单元使用 WinApi(如果您定义了标志,还使用 WMI)?