Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CallNTPowerInformation unter Vista (https://www.delphipraxis.net/128922-callntpowerinformation-unter-vista.html)

RaSoWa1 9. Feb 2009 15:19


CallNTPowerInformation unter Vista
 
Hallo

mit diesem Code habe ich bisher die CPU-Frequenz ermittelt. Leider funktioniert dieser Code bei mir nicht mehr unter Vista.
Delphi-Quellcode:
  err := CallNTPowerInformation(11, nil, 0, @ppi, sizeof(TProcessorPowerInfo));
liefert err = 3221225507.


Was kann die Ursache sein?
Welche Lösungen gibt es?

Gruß, Klaus

Mr_G 9. Feb 2009 15:49

Re: CallNTPowerInformation unter Vista
 
Was hast du denn für ein Vista? 64 Bit oder 32 Bit? Und hast du evtl. mehrere CPUs bzw. Kerne?

RaSoWa1 9. Feb 2009 16:24

Re: CallNTPowerInformation unter Vista
 
Ich habe ein 32 Bit-Vista, und 4 Kerne.

smallsmoker 9. Feb 2009 16:54

Re: CallNTPowerInformation unter Vista
 
für cpu infos benutze ich
Delphi-Quellcode:
function GetCPUCount: DWord;
var
  SysInfo: TSystemInfo;
begin
  GetSystemInfo(SysInfo);
  Result := SysInfo.dwNumberOfProcessors;
end;

function CPUClock(const intDelayTime: integer = 50): double;
var
  TimerHi, TimerLo: DWORD;
  PriorityClass, Priority: Integer;
begin
  // saves thread priority for the process
  PriorityClass := GetPriorityClass(GetCurrentProcess);
  Priority := GetThreadPriority(GetCurrentThread);

  // sets priority to REAL-TIME
  SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);

  // "delay" for priority effect
  Sleep(10);

  asm
    dw 310Fh // rdtsc
    mov TimerLo, eax
    mov TimerHi, edx
  end;

  // waits for calculations
  Sleep(intDelayTime);

  asm
    dw 310Fh // rdtsc
    sub eax, TimerLo
    sbb edx, TimerHi
    mov TimerLo, eax
    mov TimerHi, edx
  end;

  // restores process priority
  SetThreadPriority(GetCurrentThread, Priority);
  SetPriorityClass(GetCurrentProcess, PriorityClass);

  // sets the result with CPU clock frequency
  result := TimerLo / (1000.0 * intDelayTime);
end;

RaSoWa1 9. Feb 2009 17:14

Re: CallNTPowerInformation unter Vista
 
Danke für deine Hilfe,

aber diesen Code habe ich auch in meinem Archiv, versehen mit dem Hinweis: "nur für Pentium-Rechner".
Mein voriger Rechner, Xp und AMD mit 2 Kernen, hat bei wenig Last die Taktfrequenz heruntergeregelt. Diese Funktion lieferte daher bei mir nur den augenblickliche Takt, nicht dem maximal möglichen.

Gruß Klaus.

Mr_G 9. Feb 2009 20:27

Re: CallNTPowerInformation unter Vista
 
Also das Problem liegt nicht bei Vista sondern bei der Anzahl der Kerne. Du bekommst für jeden Kern eine solche Stuktur und der angegebene Fehler entspricht demnach STATUS_BUFFER_TOO_SMALL.
Ich hab das ganze mal so verwendet:
Delphi-Quellcode:
procedure TForm.ButtonClick(Sender: TObject);
var SysInfo: SYSTEM_INFO;
    PowerInfos: Pointer;
    PowerInfoArray: array of PROCESSOR_POWER_INFORMATION;
    size, ret: Cardinal;
    i: Integer;
begin
  GetSystemInfo(SysInfo);
  size := SizeOf(PROCESSOR_POWER_INFORMATION) * SysInfo.dwNumberOfProcessors;
  GetMem(PowerInfos, size);
  ZeroMemory(PowerInfos, size);
  ret := CallNTPowerInformation(11, nil, 0, PowerInfos, size);
  if ret = ERROR_SUCCESS then
    begin
      PowerInfoArray := PowerInfos;
      for i := 0 to SysInfo.dwNumberOfProcessors - 1 do
      begin
        Memo.Lines.Add(IntToStr(PowerInfoArray[i].Number));
        Memo.Lines.Add(IntToStr(PowerInfoArray[i].CurrentMhz));
        //...
      end;
    end
  else
    //Fehler...
  FreeMem(PowerInfos, size);
end;
Ich fürchte meine ehemaligen Basteleien sind aber alles andere als sauber. Vielleicht schaut da noch mal jemand drüber.

RaSoWa1 10. Feb 2009 12:21

Re: CallNTPowerInformation unter Vista
 
Hallo,

Danke für deine Hilfe.

Der Code funktioniert soweit. Die Werte werden angezeigt. Nur beim Beenden der Prozedur kommt immer die Fehlermeldung: "Invalid pointer operation".
Ich kann mir nicht erklären wieso.
Ich habe sogar nach FreeMem noch die Zeile " Memo1.Lines.Add('Fertig');" eingefügt. Selbst diese wird noch ausgeführt. Die Meldung kommt wirklich erst beim Rücksprung aus der Prozedur.
Es wird och alles freigegeben, oder ???

Gruß Klaus.

Apollonius 10. Feb 2009 12:32

Re: CallNTPowerInformation unter Vista
 
Die Zuweisung PowerInfoArray := PowerInfos scheint mir äußerst suspekt. Ich würde das folgendermaßen umdeklarieren:
Delphi-Quellcode:
type
TPowerInfoArray = array[0..0] of PROCESSOR_POWER_INFORMATION;
PPowerInfoArray = ^TPowerInfoArray;

var
//...
PowerInfoArray: PPowerInfoArray absolute PowerInfos;
Die Zuweisung kannst du dir durch die absolute-Direktive dann sparen. Sonst sollte alles wie gehabt funktionieren, wenn du PowerInfoArray[i] durch PowerInfoArray^[i] ersetzt.

RaSoWa1 10. Feb 2009 13:10

Re: CallNTPowerInformation unter Vista
 
Danke,

so geht es.

Gruß Klaus

Mr_G 10. Feb 2009 15:19

Re: CallNTPowerInformation unter Vista
 
Wenn ich den Code mal genauer betrachte hätte ich es heute wohl auch mit den Array-Typen gemacht. Das "absolute" war mir bis jetzt unbekannt... dennoch: sehr interessant, wenn auch nicht zwingend notwendig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz