* * *

Author Topic: get process path  (Read 1755 times)

mcland

  • New member
  • *
  • Posts: 12
Re: get process path
« Reply #15 on: October 10, 2017, 01:15:40 pm »
if in my code add this:

      PID := PE.th32ProcessID;
      writeln('proceso: ',ExtractFileName(pe.szExeFile));
      writeln('pid: ',pid);
      s2 := OpenProcess(PROCESS_QUERY_INFORMATION, False, PID);
      GetModuleFileName(s2, path, sizeof(path));
      writeln('path: ',path);
      //getmodulefilenameex(s2, 0, Pchar(path), sizeof(path));//MAX_PATH);
        //writeln('path: ',path);

then the output is...:
proceso: winlogon.exe
pid: 376
path: P:\ultimo\procesos.exe
proceso: services.exe
pid: 436
path: P:\ultimo\procesos.exe
proceso: lsass.exe
pid: 444
path: P:\ultimo\procesos.exe

always print me the path of my program, not the path of the pid of the process.

if change GetModuleFileName for GetModuleFileNameEx then the first letter of the path is unreadable (and the path is always the same)

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 350
    • Lebeau Software
Re: get process path
« Reply #16 on: October 10, 2017, 08:49:41 pm »
Code: [Select]
      s2 := OpenProcess(PROCESS_QUERY_INFORMATION, False, PID);
      GetModuleFileName(s2, path, sizeof(path));

You can't use GetModuleFileName() to query the filename of a module that is outside of your own process.  The first parameter is a module handle relative to your own process, but you are passing it a process handle instead.  You must use GetModuleFileNameEx() (or GetProcessImageFileName() or QueryFullProcessImageName()) to query the filename of a module in another process.

if change GetModuleFileName for GetModuleFileNameEx then the first letter of the path is unreadable (and the path is always the same)

Then you are using it wrong.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) open source project - Admin, Developer

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 350
    • Lebeau Software
Re: get process path
« Reply #17 on: October 10, 2017, 09:13:59 pm »
Sorry, i don't know how to use this part of the windows api.

There are plenty of online examples readily available.  You are just guessing instead of actually researching.

This code only prints process name :(

That is because 1) you are using ExtractFileName() to strip off any possible path information, and 2) pe.szExeFile doesn't contain path information to begin with.  Even the documentation says so:

Quote
szExeFile

The name of the executable file for the process. To retrieve the full path to the executable file, call the Module32First function and check the szExePath member of the MODULEENTRY32 structure that is returned. However, if the calling process is a 32-bit process, you must call the QueryFullProcessImageName function to retrieve the full path of the executable file for a 64-bit process.

Try something more like this instead:

Code: [Select]
program myprocess;

uses
  crt, sysutils, dos, jwatlhelp32, windows, process, JwaWindows;

var
  S, proc: HANDLE;
  PE: TProcessEntry32;
  buffer: array[0..MAX_PATH-1] of Char;
  OK: Boolean;
  size: DWORD;
begin
  S := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Create snapshot
  if S = INVALID_HANDLE_VALUE then
  begin
    // handle error as needed...
  end else
  try
    PE.dwSize := SizeOf(PE); // Set size before use
    OK := Process32First(S, PE);
    while OK do
    begin
      writeln('proceso: ', PE.szExeFile);
      proc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PE.th32ProcessID);
      if proc = 0 then
      begin
        // handle error as needed...
      end else
      try
        size := MAX_PATH;
        if not QueryFullProcessImageName(proc, 0, buffer, @size) then
        begin
          // handle error as needed...
        end else
          writeln('path: ', buffer);
      finally
        CloseHandle(proc);
      end;
      readkey;
      OK := Process32Next(S, PE);
    end;
    if GetLastError() <>  ERROR_NO_MORE_FILES then
    begin
      // handle error as needed...
    end;
  finally
    CloseHandle(S);
  end;
end.
« Last Edit: October 10, 2017, 09:15:58 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) open source project - Admin, Developer

GetMem

  • Hero Member
  • *****
  • Posts: 2463
Re: get process path
« Reply #18 on: October 10, 2017, 09:52:25 pm »
@Remy Lebeau

Quote
You should be using GetProcessImageFileName() or QueryFullProcessImageName() instead.  Even the documentation for GetModuleFileNameEx() says so:
Thanks.

I did not find PROCESS_QUERY_LIMITED_INFORMATION declared in FPC. The same is true for QueryFullProcessImageName, so I modified the code a little bit. It works fine now with Lazarus trunk/FPC 3.0.2:
Code: Pascal  [Select]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses
  4.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  5.   cthreads,
  6.   {$ENDIF}{$ENDIF}
  7.   Classes,
  8.   JwaWindows;
  9.  
  10.  
  11. const
  12.   PROCESS_QUERY_LIMITED_INFORMATION = $1000;
  13.  
  14. var
  15.   S, proc: HANDLE;
  16.   PE: TProcessEntry32;
  17.   us: UnicodeString;
  18.   OK: Boolean;
  19.   size: DWORD;
  20.  
  21.   function QueryFullProcessImageName(hProcess:HANDLE; dwFlags: DWord; lpExeName:LPWSTR;
  22.     var lpdwSize:DWORD):BOOL; stdcall; external 'kernel32' name 'QueryFullProcessImageNameW';
  23.  
  24. begin
  25.   S := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Create snapshot
  26.   if S = INVALID_HANDLE_VALUE then
  27.   begin
  28.     // handle error as needed...
  29.   end else
  30.   try
  31.     PE.dwSize := SizeOf(PE); // Set size before use
  32.     OK := Process32First(S, PE);
  33.     while OK do
  34.     begin
  35.       writeln('Image name: ', PE.szExeFile);
  36.       proc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PE.th32ProcessID);
  37.       if proc = 0 then
  38.       begin
  39.         // handle error as needed...
  40.         writeln('Image path: -');
  41.       end else
  42.       try
  43.         size := MAX_PATH;
  44.         SetLength(us, size);
  45.         if not QueryFullProcessImageName(proc, 0, @us[1], size) then
  46.         begin
  47.           // handle error as needed...
  48.           writeln('Image path: -');
  49.         end else
  50.         begin
  51.           SetLength(us, size);
  52.           writeln('Image path: ', us);
  53.         end;
  54.       finally
  55.         CloseHandle(proc);
  56.       end;
  57.       Readln;
  58.       OK := Process32Next(S, PE);
  59.     end;
  60.     if GetLastError() <>  ERROR_NO_MORE_FILES then
  61.     begin
  62.       // handle error as needed...
  63.     end;
  64.   finally
  65.     CloseHandle(S);
  66.   end;
  67. end.
« Last Edit: October 10, 2017, 10:02:17 pm by GetMem »

ASerge

  • Sr. Member
  • ****
  • Posts: 472
Re: get process path
« Reply #19 on: October 11, 2017, 01:11:39 am »
The same with the discussion :): Get list of process

mcland

  • New member
  • *
  • Posts: 12
Re: get process path
« Reply #20 on: October 14, 2017, 10:59:58 am »
This works ok, only csrss.exe not shows the path
thanks!

@Remy Lebeau

Quote
You should be using GetProcessImageFileName() or QueryFullProcessImageName() instead.  Even the documentation for GetModuleFileNameEx() says so:
Thanks.

I did not find PROCESS_QUERY_LIMITED_INFORMATION declared in FPC. The same is true for QueryFullProcessImageName, so I modified the code a little bit. It works fine now with Lazarus trunk/FPC 3.0.2:
Code: Pascal  [Select]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses
  4.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  5.   cthreads,
  6.   {$ENDIF}{$ENDIF}
  7.   Classes,
  8.   JwaWindows;
  9.  
  10.  
  11. const
  12.   PROCESS_QUERY_LIMITED_INFORMATION = $1000;
  13.  
  14. var
  15.   S, proc: HANDLE;
  16.   PE: TProcessEntry32;
  17.   us: UnicodeString;
  18.   OK: Boolean;
  19.   size: DWORD;
  20.  
  21.   function QueryFullProcessImageName(hProcess:HANDLE; dwFlags: DWord; lpExeName:LPWSTR;
  22.     var lpdwSize:DWORD):BOOL; stdcall; external 'kernel32' name 'QueryFullProcessImageNameW';
  23.  
  24. begin
  25.   S := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Create snapshot
  26.   if S = INVALID_HANDLE_VALUE then
  27.   begin
  28.     // handle error as needed...
  29.   end else
  30.   try
  31.     PE.dwSize := SizeOf(PE); // Set size before use
  32.     OK := Process32First(S, PE);
  33.     while OK do
  34.     begin
  35.       writeln('Image name: ', PE.szExeFile);
  36.       proc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PE.th32ProcessID);
  37.       if proc = 0 then
  38.       begin
  39.         // handle error as needed...
  40.         writeln('Image path: -');
  41.       end else
  42.       try
  43.         size := MAX_PATH;
  44.         SetLength(us, size);
  45.         if not QueryFullProcessImageName(proc, 0, @us[1], size) then
  46.         begin
  47.           // handle error as needed...
  48.           writeln('Image path: -');
  49.         end else
  50.         begin
  51.           SetLength(us, size);
  52.           writeln('Image path: ', us);
  53.         end;
  54.       finally
  55.         CloseHandle(proc);
  56.       end;
  57.       Readln;
  58.       OK := Process32Next(S, PE);
  59.     end;
  60.     if GetLastError() <>  ERROR_NO_MORE_FILES then
  61.     begin
  62.       // handle error as needed...
  63.     end;
  64.   finally
  65.     CloseHandle(S);
  66.   end;
  67. end.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus