Ver Mensaje Individual
  #1  
Antiguo 19-11-2010
BrunoBsso BrunoBsso is offline
Miembro
 
Registrado: nov 2009
Ubicación: Berisso, Buenos Aires, Argentina
Posts: 239
Reputación: 15
BrunoBsso Va por buen camino
Lightbulb [Aporte] Buscar/Matar procesos y ejecutar un EXE

Hola Club.
Bueno, hace poco estuve necesitando estas 3 cosas y las soluciones que encontré por varios lados no me convencían mucho así que hice algunos procedimientos (basados en ejemplos y unos retoques míos) que me sirvieron de maravilla. Sobretodo con la arquitectura x64.
Bueno, acá les dejo el código y un adjunto con todo (no es una unit, solo código):
Código Delphi [-]
uses
  System, SysUtils, Windows, TlHelp32, Forms;

function ClearFileName(AExeName: String): TFileName;
{ Sirve para sistemas de arquitectura x64 donde Windows agrega " *32" a los
  procesos que corren con arquitectura x86 }
{ Copia el FileName hasta el espacio en blanco }
var
  i: integer;
begin
  { Marcás el final de la cadena como un espacio vacío }
  i := LastDelimiter(' ', AExeName);
  if (i = 0) then { Si no hay ningún espacio vacío le das el máximo de caracteres }
    i := MaxInt;
  { Copiás desde el inicio hasta el anterior al máximo }
  Result := Copy(AExeName, 0, i - 1);
  { explorer.exe *32 -> el " " aparece en la posición 13, necesitás copiar 12 }
end;

function ProcessExists(AExeName: String): boolean;
var
  ContinueLoop: LongBool;
  FSnapshotHandle: THandle;
  FProcess: TProcessEntry32;
  FExeFound: TFileName;
begin
  { Limpias el hacés un genérico para el FileName }
  AExeName := UpperCase(ClearFileName(AExeName));
  Result := False;
  { Creas un Handle para leer procesos }
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  { Creás un buffer de procesos }
  FProcess.dwSize := SizeOf(FProcess);
  { ContinueLoop es un flag que busca el siguiente proceso y, si hay, lo guarda en FProcess }
  ContinueLoop := Process32First(FSnapshotHandle, FProcess);
  while (ContinueLoop) and NOT(Result) do
  begin
    { Almacenás el nombre "genéroco" del proceso encontrado }
    FExeFound := UpperCase(ClearFileName(ExtractFileName(FProcess.szExeFile)));
    Result := (FExeFound = AExeName);
    ContinueLoop := Process32Next(FSnapshotHandle, FProcess);
  end;
  { Cerrás el Handle }
  CloseHandle(FSnapshotHandle);
end;

procedure ExecuteAndWait(AExeName: String; uCmdShow: Cardinal);
{ Tiene que ejecutar el programa y esperar que aparezca para
  terminar el proceso }
var
  Path: PAnsiChar;
begin
  if NOT(FileExists(AExeName)) then
    Exit;
  { El PAnsiChar es necesario (al menos en D2010) para llamar a WinExec }
  Path := PAnsiChar(AnsiString(AExeName));
  WinExec(Path, uCmdShow);
  { Puede ser que tarde en llegar el mensaje de Exec así que lo "obligás" }
  Application.ProcessMessages;

  { Para prevenir que tarde, lo buscás hasta que aparece }
  while NOT(ProcessExists(AExeName)) do
    Sleep(250);

  { Recibís/Enviás todos los mensajes }
  Application.ProcessMessages;
end;

function ProcessKill(AExeName: String; Iterative: boolean = TRUE): boolean;
const
  TERMINATE = $0001;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcess: TProcessEntry32;
  FExeFound: TFileName;
Label NO_ITERATIVE;
begin
  Result := False;
  { Limpias el hacés un genérico para el FileName }
  AExeName := UpperCase(ClearFileName(AExeName));
  { Creas un Handle para leer procesos }
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  { Creás un buffer de procesos }
  FProcess.dwSize := SizeOf(FProcess);
  { ContinueLoop es un flag que busca el siguiente proceso y, si hay, lo guarda en FProcess }
  ContinueLoop := Process32First(FSnapshotHandle, FProcess);
  while (ContinueLoop) do
  begin
    { Almacenás el nombre "genéroco" del proceso encontrado }
    FExeFound := UpperCase(ClearFileName(ExtractFileName(FProcess.szExeFile)));
    if (FExeFound = AExeName) then
    begin
      Result := True;
      { Para matarlo lo debés abrir con el flag de TERMINATE }
      TerminateProcess(OpenProcess(TERMINATE, BOOL(0), FProcess.th32ProcessID),
        0);
      if NOT(Iterative) then { Si no es iterativo sale directamente a cerrar el Handle }
        GoTo NO_ITERATIVE;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcess);
  end;
NO_ITERATIVE :
  CloseHandle(FSnapshotHandle);
end;

Espero que si alguien lo necesita le sirva.
Saludos.
Archivos Adjuntos
Tipo de Archivo: zip Procesos.zip (1,5 KB, 95 visitas)
Responder Con Cita