Avatar billede lequet Nybegynder
07. oktober 2002 - 22:49 Der er 4 kommentarer og
1 løsning

Omskrivning af denne kode

OK, her kommer lige en ordentlig gang kode. Koden har jeg fundet på planetsourcecode.com og den virker faktisk helt fint. Nu er problemet bare at det er lavet som et dos program. Jeg skal bruge det i et windows program. Jeg har forsøgt at omskrive main funktionen, så den returnerer værdien istedet for blot at udskrive den, men det gav enten fejl eller også returnerede den bare 0.

Så kort fortalt : Jeg vil gerne have omskrevet denne kode, så det kan bruges i stil med dette :

Label->Caption = CPUSage() ;

Hvor CPUSage() er den nuværende main()

Håber det er til at forstå :) Koden kommer så her (Sorry, den er lidt lang, men tog det hele med for en sikkerheds skyld)



#include <windows.h>
#include <conio.h>
#include <stdio.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;

typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

PROCNTQSI NtQuerySystemInformation;


void main(void)
{
    SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
    SYSTEM_TIME_INFORMATION        SysTimeInfo;
    SYSTEM_BASIC_INFORMATION      SysBaseInfo;
    double                        dbIdleTime;
    double                        dbSystemTime;
    LONG                          status;
    LARGE_INTEGER                  liOldIdleTime = {0,0};
    LARGE_INTEGER                  liOldSystemTime = {0,0};

    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
                                          GetModuleHandle("ntdll"),
                                        "NtQuerySystemInformation"
                                        );

    if (!NtQuerySystemInformation)
        return;

    // get number of processors in the system
    status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
    if (status != NO_ERROR)
        return;

    printf("\nCPU Usage (press any key to exit):    ");
    while(!_kbhit())
    {
        // get new system time
        status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
        if (status!=NO_ERROR)
            return;

        // get new CPU's idle time
        status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
        if (status != NO_ERROR)
            return;

        // 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;

            printf("\b\b\b\b%3d%%",(UINT)dbIdleTime);
      }

        // store new CPU's idle and system time
        liOldIdleTime = SysPerfInfo.liIdleTime;
        liOldSystemTime = SysTimeInfo.liKeSystemTime;

        // wait one second
        Sleep(1000);
    }
    printf("\n");
}
Avatar billede soreno Praktikant
07. oktober 2002 - 22:58 #1
jeg havde lige noget liggende i gemmeren..:
#include <windows.h>
#include <stdio.h>
#include <stdlib.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;

typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

int getCpuLoad_winnt()
{
  PROCNTQSI NtQuerySystemInformation;

  SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
  SYSTEM_TIME_INFORMATION SysTimeInfo;
  SYSTEM_BASIC_INFORMATION SysBaseInfo;
  double dbIdleTime;
  double dbSystemTime;
  LONG status;
  LARGE_INTEGER liOldIdleTime = {0,0};
  LARGE_INTEGER liOldSystemTime = {0,0};
  HINSTANCE dll;

  dll = LoadLibrary("ntdll.dll");
  if(dll != NULL)
  {
      NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(dll, "NtQuerySystemInformation");
  }
  FreeLibrary(dll); 

  if(!NtQuerySystemInformation)
  {
      //printf("*errror* NtQuerySystemInformation\n");
      return -1;
  }

  // get number of processors in the system
  status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
  if (status != NO_ERROR)
  {
      //printf("*error* SysBaseInfo\n");
      return -1;
  }

  for(int i=0;i<2;i++)
  {
      // get new system time
      status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
      if(status!=NO_ERROR)
      {
        //printf("*error* SysTimeInf\n");
        return -1;
      }
     
      // get new CPU's idle time
      status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
      if(status != NO_ERROR)
      {
        //printf("*error* SysPerfInfo\n");
        return -1;
      }
 
      // 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;
      }
      liOldIdleTime = SysPerfInfo.liIdleTime;
      liOldSystemTime = SysTimeInfo.liKeSystemTime;

      //sov et sekund
      Sleep(1000);

  }
  return (UINT)dbIdleTime;
}

int main(int argc, char **argv)
{
  printf("cpu_load: %i\n", getCpuLoad_winnt());

  return 0;
}

der er nok lavet en anelse om på strukturen - men princippet er den samme, nemlig at hente current cpu load på en nt maskine via ntdll.dll
Avatar billede lequet Nybegynder
07. oktober 2002 - 23:13 #2
Takker prøver lige :)
Avatar billede lequet Nybegynder
07. oktober 2002 - 23:17 #3
Det giver resultatet -1 (lyder ikke som om det kan være sandt :)

Men dette ser i mine øjne heller ikke korrekt ud :

CPU->Caption = printf("cpu_load: %i\n", getCpuLoad_winnt()) ;

Eller er det rigtigt nok? I så fald, hvad kan der ellers være galt
Avatar billede soreno Praktikant
07. oktober 2002 - 23:21 #4
nej, sådan kan du ikke bruge det..!
jeg har en ide om at du måske bruger c++ builder ?
CPU er et tekstfelt ?
Caption sætter teksten ?
prøv:
CPU->Caption = getCpuLoad_winnt();

eller måske:
char buffer[5];
itoa(getCpuLoad_winnt(), buffer, 10);
CPU->Caption = buffer;
Avatar billede lequet Nybegynder
07. oktober 2002 - 23:26 #5
Tænkte jeg nok, synes heller ikke printf passede ind der :)

Dine antagelser er korrekte, og nu virker det sørme også :)

Takker mange gange for den hurtige hjælp
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester