CPU-Auslastung auf 64bit Windows ermitteln



  • Ich benutze folgenden Code um die CPU-Auslastung im ganzen zu ermitteln. Er stammt glaube ich aus diesem Forum, ich habe nur eine Klasse daraus gemacht.
    Er funktioniert unter allen Systemen die 32 bit verwenden. XP64 oder auch Windows 7 x64 funktioniert nicht, das Resultat ist dort schlichtweg 0.

    Weiß jemand was man tun muss, damit es auch auf 64bit Windows klappt?

    MfG

    Header:

    //---------------------------------------------------------------------------
    
    #ifndef cpuH
    #define cpuH
    
    #include <windows.h> 
    #include <conio.h>
    #include <stdio.h>
    
    #include "cSystemUtility.h"
    
    #define SystemBasicInformation 0
    #define SystemPerformanceInformation 2
    #define SystemTimeInformation 3
    
    #define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
    //---------------------------------------------------------------------------
    
    typedef struct 
    { 
    DWORD dwUnknown1; 
    ULONG uKeMaximumIncrement; 
    ULONG uPageSize; 
    ULONG uMmNumberOfPhysicalPages; 
    ULONG uMmLowestPhysicalPage; 
    ULONG uMmHighestPhysicalPage; 
    ULONG uAllocationGranularity; 
    PVOID pLowestUserAddress; 
    PVOID pMmHighestUserAddress; 
    ULONG uKeActiveProcessors; 
    BYTE bKeNumberProcessors; 
    BYTE bUnknown2; 
    WORD wUnknown3; 
    } SYSTEM_BASIC_INFORMATION; 
    
    typedef struct 
    { 
    LARGE_INTEGER liIdleTime; 
    DWORD dwSpare[76]; 
    } SYSTEM_PERFORMANCE_INFORMATION; 
    
    typedef struct 
    { 
    LARGE_INTEGER liKeBootTime; 
    LARGE_INTEGER liKeSystemTime; 
    LARGE_INTEGER liExpTimeZoneBias; 
    ULONG uCurrentTimeZoneId; 
    DWORD dwReserved; 
    } SYSTEM_TIME_INFORMATION; 
    
    // ntdll!NtQuerySystemInformation (NT specific!) 
    // 
    // The function copies the system information of the 
    // specified type into a buffer 
    // 
    // NTSYSAPI 
    // NTSTATUS 
    // NTAPI 
    // NtQuerySystemInformation( 
    // IN UINT SystemInformationClass, // information type 
    // OUT PVOID SystemInformation, // pointer to buffer 
    // IN ULONG SystemInformationLength, // buffer size in bytes 
    // OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit 
    // // variable that receives 
    // // the number of bytes 
    // // written to the buffer 
    // ); 
    typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG); 
    
    class cpu
    {
        public:
            cpu();
            ~cpu();
            double getCpuPercent(void);
        private:
            PROCNTQSI NtQuerySystemInformation;
            SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
            SYSTEM_TIME_INFORMATION SysTimeInfo;
            SYSTEM_BASIC_INFORMATION SysBaseInfo;
            double dbIdleTime;
            double dbSystemTime;
            LONG status;
            LARGE_INTEGER liOldIdleTime;
            LARGE_INTEGER liOldSystemTime;
    
            cSystemUtility sysutil;
    };
    
    //------------------------------------------------------------------------------
    
    #endif
    

    CPP:

    //---------------------------------------------------------------------------
    #pragma hdrstop
    
    #include "cpu.h"
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    
    cpu::cpu()
    {
        liOldIdleTime.QuadPart = 0;
        liOldSystemTime.QuadPart = 0;
    }
    
    cpu::~cpu()
    {
    
    }
    
    double cpu::getCpuPercent()
    {
    
        HANDLE   hToken;
        TOKEN_PRIVILEGES   tkp;
    
        // wenn wir nicht 95 / 98 / ME haben, muessen wir Privilegien beschaffen
        if (sysutil.getWindowsType() != wt98ME)
        {
    
            //   Get   a   token   for   this   process
            OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    
            //   Get   the   LUID   for   the   shutdown   privilege.
            LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
    
            tkp.PrivilegeCount   =   1;     //   one   privilege   to   set
            tkp.Privileges[0].Attributes   =   SE_PRIVILEGE_ENABLED;
    
            //   Get   the   shutdown   privilege   for   this   process.
            AdjustTokenPrivileges(hToken,   FALSE,   &tkp,   0,
                          (PTOKEN_PRIVILEGES)NULL,   0);
    
            //   Cannot   test   the   return   value   of   AdjustTokenPrivileges.
            //  if   (GetLastError()   !=   ERROR_SUCCESS)
            //          error("AdjustTokenPrivileges");
    
            //   Shut   down   the   system   and   force   all   applications   to   close.
    
        }
    
    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
    GetModuleHandle("ntdll"),
    "NtQuerySystemInformation"
    );
    
    if (!NtQuerySystemInformation)
    return 0;
    
    // get number of processors in the system
    status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); 
    if (status != NO_ERROR)
    return 0;
    
    // get new system time
    status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0); 
    if (status!=NO_ERROR)
       return 0;
    
    // get new CPU's idle time
    status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL); 
    if (status != NO_ERROR) 
       return 0; 
    
    // if it's a first call - skip it 
    if (liOldIdleTime.QuadPart != 0)
       { 
       // CurrentValue = NewValue - OldValue 
       dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); 
      dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); 
    
       // CurrentCpuIdle = IdleTime / SystemTime
       dbIdleTime = dbIdleTime / dbSystemTime; 
    
       // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors 
       dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; 
    
       }
    
    // store new CPU's idle and system time 
    liOldIdleTime = SysPerfInfo.liIdleTime;
    liOldSystemTime = SysTimeInfo.liKeSystemTime;
    
    // wait one second
    //Sleep(1000); wird von nem Timer übernomen
    
    return  dbIdleTime;
    
    }
    


  • Dieser Thread wurde von Moderator/in akari aus dem Forum VCL (C++ Builder) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • hatte gerade das selbe problem. der ntquery aufruf für die struktur SYSTEM_PERFORMANCE_INFORMATION schlägt unter vista bzw 7 x64 fehl. wenn du in die msdn schaust wirst du feststellen das microsoft da schon einen vermerk gemacht hat das man GetSystemTimes() benutzen soll.

    du benutzt nun also nicht SysPerfInfo.liIdleTime sondern die IdleTime die von GetSystemTimes() kommt. Und schon sollte es wieder funktionien.



  • Weißt du eigentlich, was du da machst? Dann erkläre mir doch mal, warum du das Privileg zum Runterfahren von Windows aktivierst, wenn du die Prozessorauslastung ermitteln willst.



  • ich nehme mal an das dieser codeabschnitt garnich da rein gehört. auch das unter dem letzten kommentar "shut down all..." nix mehr kommt deutet darauf hin. vieleicht ein copy and paste fehler 🙂



  • Copy Paste Fehler! Das stammt aus meinem shutdown tool und ist dort reingeraten^^ GetSystemTimes() werde ich bei Zeiten mal testen.

    MfG



  • Meine "winbase.h", die mit BCB6 mitgeliefert wird, enthält keine GetSystemTimes(), dafür ist sie zu alt. Das Benutzen einer winbase.h aus einem aktuellen SDK bringt dutzende Compiler-Fehler.

    Wo bekomme ich eine aktuelle C Builder kompatible Datei her? Oder was kann ich tun?

    MfG


Anmelden zum Antworten