各位下午好!
我目前正在开发一个小型系统管理工具,其风格非常类似于Firemonkey
( Delphi XE2
) 中的 Windows 8 任务管理器。目前,我正在尝试TPanels
使用TGridLayout
. 我在设计时添加了所有面板,直到对实际功能进行排序。
我的问题在于将数据从 WMI 输出到数组中。我已经有一个不涉及数组的工作版本,但是我在创建更具动态性且不太可能在不同配置中跌倒的东西时遇到了麻烦。这是当前不完全工作的代码;
Procedure CoreUsage;
const
WbemUser ='';
WbemPassword ='';
WbemComputer ='localhost';
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
i : Integer;
begin
try
CoInitialize(nil);
try
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation WHERE NOT Name="_Total" AND NOT Name="0,_Total"',
'WQL',
wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
begin
if oEnum.Next(1, FWbemObject, iValue) = 0 then
begin
for i := 0 to 63 do
begin
CoreName[i] := FWbemObject.Name;
CoreUsage[i] := FWbemObject.PercentProcessorTime;
end;
end;
FWbemObject:=Unassigned;
end;
finally
CoUninitialize;
end;
end;
end;
CoreUsage
并且CoreName
都是[0..63]
相关类型长度的全局变量数组(CoreName 属于String
,CoreUsage 属于Uint64
)。这样做的问题是它在所有面板中显示相同的值,而不是基于每个核心(这是我的意图)。这几乎就像它没有通过 0..63,而只是检索第一个值。
我本质上是想将每个值分配给数组中的一个值,因为这样我就可以轻松读取特定于核心的详细信息,而无需硬编码。在我完全在我的开发机器上工作的代码中,我必须手动完成并使用这样的东西;
if AnsiContainsText(FWbemObject.Name,'3') then
begin
CoreName[3] := FWbemObject.Name;
CoreUsage[3] := FWbemObject.PercentProcessorTime;
end
正如你所看到的,它是硬编码的,但在具有 3 个 CPU 的系统中会变得不稳定(在上面的例子中)。显然 '3' 被替换为适当的数组 id,从 0 一直到 63(尽管 0 是专门寻找的0,0
)。这样做的问题是CPU格式实际上是( CPUx,y
在哪里,核心是哪里)。它也不是我会因为它不可靠而简单地使用的代码。例如,对于具有 2 个八核 CPU(16 个逻辑核心)的系统,核心名称可能是然后。x
y
0,0 .. 0,7
1,0 .. 1,7
同样重要的是,代码本身维护起来是一场噩梦,但可能会缩短为单个for i :=
子句并使用IntToStr
. 但确保它有效的问题仍然存在。
我确信有一种完全可能的方法来做到这一点,但我无法弄清楚。我确实尝试过使用;
for VarArrayLowBound(FWbemObject.Name, 1) to VarArrayHighBound(FWbemObject.Name, 1) do
和
for VarArrayLowBound(FWbemObject.PercentProcessorTime, 1) to VarArrayHighBound(FWbemObject.PercentProcessorTime, 1) do
但可惜,没有这样的运气。有任何想法吗?