Recent

Author Topic: How to get process information cpu,memory pid  (Read 17484 times)

DelFly

  • New Member
  • *
  • Posts: 38
How to get process information cpu,memory pid
« on: August 12, 2013, 03:48:52 pm »
Its long time ago i used delphi, so some things are rusty and lazarus is slightly different sometimes. for me(windows) program i need process info. at least memory and cpu usage. For the pid i found JwaTlHelp32 but pid i can read from file to. . but for memory and cpu i cant find anything.

So whats best way to read the memory and cpu useage ?
disk and network would be nice but not really needed.
I know for delphi i figured soemthing out in the past.
but afraid thats not compatible anyway, if i can find that back.
Cant touch anything on computer without hitting some bug.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1249
Re: How to get process information cpu,memory pid
« Reply #1 on: August 12, 2013, 03:55:22 pm »
Not that I know the answer, but out of curiosity, what OS?

UPDATE:  Knew I'd seen a linux based version of this conversation somewhere...
http://free-pascal-general.1045716.n5.nabble.com/How-to-get-info-about-CPU-and-Memory-usage-td5713156.html

UPDATE TO UPDATE:  Doh!  You specified Windows.  Sorry, no idea...
« Last Edit: August 12, 2013, 04:04:19 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

DelFly

  • New Member
  • *
  • Posts: 38
Re: How to get process information cpu,memory pid
« Reply #2 on: August 12, 2013, 04:13:07 pm »
Wrote above, for windows.
Cant touch anything on computer without hitting some bug.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: How to get process information cpu,memory pid
« Reply #3 on: August 12, 2013, 04:33:19 pm »
Why wouldn't it be compatible? A lot of this kind Delphi code seems to be, as it's just calling the Windows API.

You could have a search through sites like stackoverflow.com for Delphi code and post if you hit problems converting it.
(Assuming a forum and wiki search didn't return any useful info)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 753
Re: How to get process information cpu,memory pid
« Reply #4 on: August 12, 2013, 05:19:33 pm »
look for   :o   PasmonTray
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

DelFly

  • New Member
  • *
  • Posts: 38
Re: How to get process information cpu,memory pid
« Reply #5 on: August 12, 2013, 06:59:29 pm »
Thanks.. meanwhile i found my files back or at least part to..
ill look at the pasmontray to.  :)
Cant touch anything on computer without hitting some bug.

DelFly

  • New Member
  • *
  • Posts: 38
Re: How to get process information cpu,memory pid
« Reply #6 on: August 12, 2013, 08:02:22 pm »
pasmonytar seems tray util. thats not what i need. this code.

Code: [Select]
program ProcessFindPID;
 
{$mode objfpc}{$H+}
 
uses
  Classes, Sysutils, Windows, JwaTlHelp32;
 
function QueryFullProcessImageName(hProcess: HANDLE; dwFlags: DWORD; var lpExeName: LPTSTR;
var lpdwSize: LPDWORD): BOOL; stdcall; external 'KERNEL32.dll';
 
function FindInProcesses(const PName: string): DWord;
  // Looks for process with PName executable and return
var
  i: integer;
  CPID: DWORD;
  CProcName: array[0..259] of char;
  S: HANDLE;
  PE: TProcessEntry32;
begin
  Result := 0;
  CProcName := '';
  S := CreateToolHelp32Snapshot(TH32CS_SNAPALL, 0); // Create snapshot
  PE.DWSize := SizeOf(PE); // Set size before use
  I := 1;
  if Process32First(S, PE) then
    repeat
      CProcName := PE.szExeFile;
      CPID := PE.th32ProcessID;
      //if CProcName = '' then Writeln(IntToStr(i) + ' - (' + IntToStr(CPID) + ') Failed to get a process name')
      Inc(i);
      if UpperCase(CProcName) = UpperCase(PName) then
        { Found the name. Set Result to the PID of process found }
        Result := CPID;
    until not Process32Next(S, PE);
  CloseHandle(S);
end;
 
begin
  writeln('Explorer.exe has process id '+inttostr(FindInProcesses('explorer.exe')));
end.

Works fine to get the pid. im sure there more options possible.
As example i have the pid but need to know if the process is still running.
ANd with JwaTlHelp32 i think you can also read cpu info and memory useage of the process by pid. Only finding the manual... google not really helpfull.
Tried some delphi code "processinfo" but that seems not really compatible with lazarus and thrping errors.

Most important what i need is the option to check if pid is still running.
memory useage and cpu would be nice.
Cant touch anything on computer without hitting some bug.

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 753
Re: How to get process information cpu,memory pid
« Reply #7 on: August 13, 2013, 02:57:38 am »
hello,
you can use WMI like this to list all processes running with memory and cpu informations :
Quote
uses
  Windows,
  Variants,
  ActiveX,
  JwaWbemCli;
 const
  RPC_C_AUTHN_LEVEL_DEFAULT = 0;
  RPC_C_IMP_LEVEL_IMPERSONATE = 3;
  RPC_C_AUTHN_WINNT = 10;
  RPC_C_AUTHZ_NONE = 0;
  RPC_C_AUTHN_LEVEL_CALL = 3;
  EOAC_NONE = 0;
{$R *.lfm}
procedure Test_IWbemServices_ExecQuery;
const
  strLocale    = '';
  strUser      = '';
  strPassword  = '';
  strNetworkResource = 'root\cimv2';
  strAuthority       = '';
  WQL                = 'SELECT * FROM Win32_Process';
//  WQL                = 'SELECT * FROM Win32_Process WHERE NAME="myprocess.exe"';
var
  FWbemLocator         : IWbemLocator;
  FWbemServices        : IWbemServices;
  FUnsecuredApartment  : IUnsecuredApartment;
  ppEnum               : IEnumWbemClassObject;
  apObjects            : IWbemClassObject;
  puReturned           : ULONG;
  pVal                 : OleVariant;
  pType                : Integer;
  plFlavor             : Integer;
  Succeed              : HRESULT;
  TheResult            : String;
  ProcessRunning       : Boolean;
begin
  // Set general COM security levels --------------------------
  // Note: If you are using Windows 2000, you need to specify -
  // the default authentication credentials for a user by using
  // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
  // parameter of CoInitializeSecurity ------------------------
  Succeed := CoInitializeSecurity(nil, -1, nil, nil, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nil, EOAC_NONE, nil);
  if (Failed(Succeed)) AND (Succeed <> RPC_E_TOO_LATE) then Exit;
  // Obtain the initial locator to WMI -------------------------
  if Succeeded(CoCreateInstance(CLSID_WbemLocator, nil, CLSCTX_INPROC_SERVER, IID_IWbemLocator, FWbemLocator)) then
  try
    // Connect to WMI through the IWbemLocator::ConnectServer method
    if Succeeded(FWbemLocator.ConnectServer(strNetworkResource, strUser, strPassword, strLocale,  WBEM_FLAG_CONNECT_USE_MAX_WAIT, strAuthority, nil, FWbemServices)) then
    try
      // Set security levels on the proxy -------------------------
      if Failed(CoSetProxyBlanket(FWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nil, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nil, EOAC_NONE)) then Exit;
      if Succeeded(CoCreateInstance(CLSID_UnsecuredApartment, nil, CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, FUnsecuredApartment)) then
      try
        // Use the IWbemServices pointer to make requests of WMI
        //Succeed := FWbemServices.ExecQuery('WQL', WQL, WBEM_FLAG_FORWARD_ONLY OR WBEM_FLAG_RETURN_IMMEDIATELY, nil, ppEnum);
        ProcessRunning := False;
        Succeed := FWbemServices.ExecQuery('WQL', WQL, WBEM_FLAG_FORWARD_ONLY, nil, ppEnum);
        if Succeeded(Succeed) then
        begin
//          Writeln('Running Wmi Query..Press Enter to exit');
           // Get the data from the query

           while (ppEnum.Next(WBEM_INFINITE, 1, apObjects, puReturned)=0) do
           begin
             ProcessRunning := True;
             apObjects.Get('Name', 0, pVal, pType, plFlavor);
             TheResult := pVal;
             apObjects.Get('ProcessID', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + InttoStr(pVal);
             apObjects.Get('WorkingSetSize', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + InttoStr(pVal);
             apObjects.Get('KernelModeTime', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + FloattoStr(Int64(pVal)/ 10000000.0);
             apObjects.Get('UserModeTime', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + FloattoStr(Int64(pVal)/ 10000000.0);
             VarClear(pVal);
             Form1.Memo1.Lines.Add(TheResult);
           end;
//        if ProcessRunning then Form1.Memo1.Lines.Add('Process is running') else
//        Form1.Memo1.Lines.Add('Process is not running');
        end
        else
       Form1.Memo1.Lines.Add(Format('Error executing WQL sentence %x',[Succeed]));
      finally
        FUnsecuredApartment := nil;
      end;
    finally
      FWbemServices := nil;
    end;
  finally
    FWbemLocator := nil;
  end;
end;

if you want to see if your process is running use :
Code: [Select]
WQL                = 'SELECT * FROM Win32_Process WHERE NAME="myprocess.exe"';
and :
Code: [Select]
       if ProcessRunning then Form1.Memo1.Lines.Add('Process is running') else
      Form1.Memo1.Lines.Add('Process is not running');     

the cpu times are in seconds since process running. ( not the percentage)
see win32_process for more fields.

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

avra

  • Hero Member
  • *****
  • Posts: 1717
    • Additional info
Re: How to get process information cpu,memory pid
« Reply #8 on: August 14, 2013, 08:09:25 am »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

qoxop

  • New Member
  • *
  • Posts: 33
Re: How to get process information cpu,memory pid
« Reply #9 on: May 06, 2014, 07:40:13 am »
Just curious... Isn't there a memory leak?
Probably VarClear(pVal); should be called after every calling apObjects.Get() ...(?) Not only at the end of the loop.

             apObjects.Get('Name', 0, pVal, pType, plFlavor);
             TheResult := pVal;
             apObjects.Get('ProcessID', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + InttoStr(pVal);
             apObjects.Get('WorkingSetSize', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + InttoStr(pVal);
             apObjects.Get('KernelModeTime', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + FloattoStr(Int64(pVal)/ 10000000.0);
             apObjects.Get('UserModeTime', 0, pVal, pType, plFlavor) ;
             TheResult += ' - ' + FloattoStr(Int64(pVal)/ 10000000.0);
             VarClear(pVal);