如何使用Delphi从远程计算机获取性能数据

时间:2009-11-12 11:14:40

标签: performance delphi winapi

鉴于我拥有适当的权利,我如何从远程计算机获取性能数据(即'Pages / Sec','Avg.Disk Queue'等)?

基本上我想写一个这样的函数:

function GetPerformanceData(aComputerName, aPerformanceIndicator: string): variant;

最好(当然)在Windows和Linux上开箱即用。

3 个答案:

答案 0 :(得分:3)

我不太清楚你的意思是“开箱即用” - 你不想对服务器进行任何修改?此外,由于您使用的是Delphi,我认为客户端是Windows - 服务器怎么样?

最简单的方法是创建一个守护进程/服务,在服务器上收集此信息,客户端上的函数可以连接并读取它。服务器可以像在apache中运行的CGI shell脚本一样简单,也可以是自定义Delphi程序。另请注意,您通常可以通过SSH在远程unix计算机上运行命令,因此您可以在远程服务器上运行类似vm_stat的操作而无需编写任何内容。 Windows具有与PsExec工具类似的功能,您可以在此处阅读: http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx

答案 1 :(得分:2)

如果启用WMI (Windows Management Instrumentation),您可以使用可用于Delphi的免费WMI component collection

  

允许访问和更新的MagWMI   使用Windows系统信息   Windows Management Instrumentation。   MagWMI提供对其的一般视图访问   使用SQL的任何WMI信息   命令,还有一些   与TCP / IP相关的专用功能   配置,如设置   适配器IP地址和计算机   名称和域/工作组。

答案 2 :(得分:1)

查看this answer

您可以重写GetPerformanceData函数以允许连接到远程注册表:

function GetPerformanceData(const RegValue: string; const ComputerName: string = ''): PPerfDataBlock;
const
  BufSizeInc = 4096;
var
  BufSize, RetVal: Cardinal;
  Key: HKEY;
begin
  BufSize := BufSizeInc;
  Result := AllocMem(BufSize);
  try
    if ComputerName = '' then
      Key := HKEY_PERFORMANCE_DATA
    else if RegConnectRegistry(PChar(ComputerName), HKEY_PERFORMANCE_DATA, Key) <> ERROR_SUCCESS then
      RaiseLastOSError;

    RetVal := RegQueryValueEx(Key, PChar(RegValue), nil, nil, PByte(Result), @BufSize);
    try
      repeat
        case RetVal of
          ERROR_SUCCESS:
            Break;
          ERROR_MORE_DATA:
            begin
              Inc(BufSize, BufSizeInc);
              ReallocMem(Result, BufSize);
              RetVal := RegQueryValueEx(Key, PChar(RegValue), nil, nil, PByte(Result), @BufSize);
            end;
          else
            RaiseLastOSError;
        end;
      until False;
    finally
      RegCloseKey(Key);
    end;
  except
    FreeMem(Result);
    raise;
  end;
end;

有关如何从返回的性能数据中检索特定计数器值的示例,请参阅该单元中的其他函数。请注意,它们都是在本地编写的,因此您需要修改它们才能将计算机名称指定为附加参数,例如:

function GetSystemUpTime(const ComputerName: string = ''): TDateTime;
const
  SecsPerDay = 60 * 60 * 24;
var
  Data: PPerfDataBlock;
  Obj: PPerfObjectType;
  Counter: PPerfCounterDefinition;
  SecsStartup: UInt64;
begin
  Result := 0;

  Data := GetPerformanceData(IntToStr(ObjSystem), ComputerName);
  try
    Obj := GetObjectByNameIndex(Data, ObjSystem);
    if not Assigned(Obj) then
      Exit;

    Counter := GetCounterByNameIndex(Obj, CtrSystemUpTime);
    if not Assigned(Counter) then
      Exit;

    SecsStartup := GetCounterValue64(Obj, Counter);
    // subtract from snapshot time and divide by base frequency and number of seconds per day
    // to get a TDateTime representation
    Result := (Obj^.PerfTime.QuadPart - SecsStartup) / Obj^.PerfFreq.QuadPart / SecsPerDay;
  finally
    FreeMem(Data);
  end;
end;

您可以通过命令lodctr /s:<filename>获取perf对象和计数器索引。 例如,'Pages / sec'计数器索引是40并且属于perf对象'Memory',索引4。 还要看看here如何解释原始计数器数据,具体取决于它们的定义。