Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Path de proceso (https://www.clubdelphi.com/foros/showthread.php?t=90288)

Ramsay 12-05-2016 04:57:51

Path de proceso
 
Hola , encontre esta funcion que me devuelve el path de un proceso de windows , tengo un programa que lista todos los procesos y los muestra en una lista , esta funcion funciona bien pero casi todos los paths los devuelve en chino , soloy muy pocos se ven los paths reales.

Funcion:

Código Delphi [-]

function GetPathFromPID(const PID: cardinal): string;
var
  hProcess: THandle;
  path: array[0..MAX_PATH - 1] of char;
begin
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then
        RaiseLastOSError;
      result := path;
    finally
      CloseHandle(hProcess)
    end
  else
    RaiseLastOSError;
end;

¿ Porque pasa esto ? ¿ Se puede solucionar ?

AgustinOrtu 12-05-2016 05:02:25

Version de Delphi?

ElKurgan 12-05-2016 07:32:11

En stack overflow se ha tratado este tema. Parece que tiene que ver con que el ordendor ejecute procesos de 32 o de 64 bits.

No se si este será tu caso, pero por probar...

Saludos

AgustinOrtu 12-05-2016 16:11:42

Otra cosa, acabo de ver que tenes un error importante

El error mas tipico y tonto de la programacion al programar en Windows: No chequear los errores

En tu codigo lo intentas hacer, pero mal

Las funciones de la API de Windows devuelven 0 para indicar que no hay error, y distinto de 0 indicando que hay error; donde el codigo retornado corresponde al codigo de error

Código Delphi [-]
function GetPathFromPID(const PID: cardinal): string;
var
  hProcess: THandle;
  path: array[0..MAX_PATH - 1] of char;
begin
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) <> 0 then // cambie = 0 por <> 0
        RaiseLastOSError;
      result := path;
    finally
      CloseHandle(hProcess)
    end
  else
    RaiseLastOSError;
end;

La pregunta de la version de Delphi es por el tema del Unicode. A partir de Delphi 2009, el tipo string es un alias de UnicodeString. Antes eran AnsiString y habia que realizar conversiones explicitas a Unicode (en algunos casos obviamente)

roman 12-05-2016 16:39:07

Cita:

Empezado por AgustinOrtu (Mensaje 505151)
Código Delphi [-]
if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) <> 0 then // cambie = 0 por <> 0
  RaiseLastOSError;

Cita:

Empezado por MSDN
Return value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

;)

LineComment Saludos

AgustinOrtu 12-05-2016 20:48:42

Vaya! me he disparado en el pie :p

Bueno, no es lo idiomatico de M$, o al menos es la primera vez que veo una funcion asi

Gracias roman por comentarlo

No he dicho nada entonces :)

Ramsay 12-05-2016 23:24:45

Ok , estoy tratando de tener el nombre de la ventana desde el pid del proceso , pero me dice el nombre de la ventana incorrecto.

El codigo :

Código Delphi [-]
    Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False,
      pid);
    SetLength(title, 255);
    SetLength(title, GetWindowText(Handle, PChar(title), Length(title)));
    CloseHandle(Handle);

¿ Porque no funciona ?

PD : Uso Delphi XE2.

ElKurgan 13-05-2016 07:33:03

Me vuelvo a repetir:

Cita:

Empezado por ElKurgan (Mensaje 505127)
En stack overflow se ha tratado este tema. Parece que tiene que ver con que el ordendor ejecute procesos de 32 o de 64 bits.

No se si este será tu caso, pero por probar...

Saludos

Si, hay que modificar un poco el código que viene ahí, pero a mi me funciona:

Código Delphi [-]
function TForm1.GetPathFromPid64(const ThePID: Cardinal): string;
type
  TQueryFullProcessImageName = function(hProcess: Thandle; dwFlags: DWORD; lpExeName: PChar; nSize: PDWORD): BOOL; stdcall;
var
  hProcess: Thandle;
  sciezka: array [0 .. MAX_PATH - 1] of Char;
  QueryFullProcessImageName: TQueryFullProcessImageName;
  nSize: cardinal;
begin
  Result := '';
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, ThePID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEX(hProcess, 0, sciezka, MAX_PATH) <> 0 then Result := sciezka
      else if Win32MajorVersion >= 6 then
      begin
        nSize := MAX_PATH;
        ZeroMemory(@sciezka, MAX_PATH);
        @QueryFullProcessImageName := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
        if Assigned(QueryFullProcessImageName) then
          if QueryFullProcessImageName(hProcess, 0, sciezka, @nSize) then Result := sciezka
      end;
    finally
      CloseHandle(hProcess);
    end;
end;

Saludos

Ramsay 13-05-2016 15:43:29

No , ese codigo funciona bien , me refiero al que mostre en el mensaje anterior , estoy tratando de capturar el nombre de la ventana del proceso , no el path , ese tema ya esta solucionado.

escafandra 13-05-2016 18:23:34

Para encontrar la ventana de un proceso debes enumerar todas las ventanas top-level hasta encontrar una del proceso requerido. Luego debes navegar hasta encontrar la ventana principal.

Código Delphi [-]
function GetWindowFromPId(PId: DWORD; var WText, WClass: String): THandle;
type
  TWinParam = record
    Handle: THandle;
    PId: DWORD;
  end;
  PWinParam = ^TWinParam;
var
  WinParam: TWinParam;
  Buffer: array [1..255] of char;
 
  function EnumWindowsProc(Handle: Thandle; lParam: LPARAM): BOOL; stdcall;
  var
    PId: DWORD;
  begin
    Result:= true;
    PId:= 0;
    GetWindowThreadProcessId(Handle, PId);
    if PWinParam(lParam).PId = PId then
    begin
      PWinParam(lParam).Handle:= Handle;
      Result:= false;
    end;
  end;
 
begin
  WinParam.PId:= PId;
  EnumWindows(@EnumWindowsProc, LPARAM(@WinParam));
  repeat
    Result:= WinParam.Handle;
    WinParam.Handle:= Windows.GetParent(Result);
  until WinParam.Handle = 0;
  GetWindowText(Result, @Buffer, 255);
  WText:= Buffer;
  GetClassName(Result, @Buffer, 255);
  WClass:= Buffer;
end;

Forma de uso:
Código Delphi [-]
var
  Caption: String;
  Clase: String;
  HWin: THandle;
begin
  HWin:= GetWindowFromPId(PID, Caption, Clase);
end;

Más información aquí


Saludos.


La franja horaria es GMT +2. Ahora son las 19:52:03.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi