Jump to content


Photo

[RESUELTO] Como detectar si mi aplicación esta en ejecución ??


  • Please log in to reply
7 replies to this topic

#1 agag4

agag4

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 posts
  • LocationMéxico

Posted 23 October 2010 - 02:06 PM

Ya se ha tratado más de una vez este tema, lo quiero abrir de nuevo para ver si me pueden ayudar en que estoy mal, tengo una aplicación que esta monitoreando si se esta ejecutando otro programa, si no esta en ejecución lo mando llamar, para hacer eso tengo un timer y adentro del evento ontimer tengo lo siguiente:


delphi
  1.   CreateMutex(nil, True, 'PROG_EXTERNO');
  2.  
  3.   // Si no esta en ejecución lo llamamos
  4.   if GetLastError <> ERROR_ALREADY_EXISTS then
  5.     WinExec('C:\PROG_EXTERNO.exe',6);



Todo funciona de maravilla la 1era vez que ejecuta el programa al revisar que no esta en ejecución, pero si intento cerrar el PROG_EXTERNO.exe atravez del administrador de tareas, vuelve entrar al evento ontimer en mi aplicación pero no lo llama porque aun supone que esta en ejecución  :|

Me faltará algun REFRESH como después de crear el Mutex ??

  • 0

#2 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 23 October 2010 - 04:06 PM

Podría pensar que no se libera completamente PROG_EXTERNO en la memoria; me sucedía algo similar al validar si un formulario estaba o no creado luego de cerrarlo por action := caFree, esto lo cambié con mejores resultado por FreeAndNil()... en fin, no va al caso, lo importante sería revisar como bien dices la forma de hacer un "refresh"


Saludos!
  • 0

#3 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 23 October 2010 - 04:09 PM

Para saber si un programa externo esta activo lo mejor es examinar la lista de procesos.

Aqui te dejo un ejemplo:


delphi
  1. program watchdog;
  2.  
  3. uses
  4.   Windows, SysUtils, PsApi, ShellApi;
  5.  
  6. function CuantosSon(Path: String): Integer;
  7. var
  8.   Procesos: array[1..1024] of DWORD;
  9.   Needed, i: DWORD;
  10.   Process: THandle;
  11.   ModName: array[0..MAX_PATH] of Char;
  12. begin
  13.   Result:= 0;
  14.   if EnumProcesses(@Procesos,SizeOf(Procesos),Needed) then
  15.   begin
  16.     for i:= 1 to (Needed div Sizeof(DWORD)) do
  17.     begin
  18.       Process := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
  19.         FALSE,Procesos[i]);
  20.       if Process <> 0 then
  21.       begin
  22.         if GetModuleFileNameEx(Process,0,ModName,SizeOf(ModName)-1)>0  then
  23.         begin
  24.           if StrIComp(ModName,PChar(Path)) = 0 then
  25.             inc(Result);
  26.         end;
  27.         CloseHandle(Process);
  28.       end;
  29.     end;
  30.   end;
  31. end;
  32.  
  33. begin
  34.   if ParamCount < 1 then
  35.     Exit;
  36.   if not FileExists(ParamStr(1))  then
  37.     Exit;
  38.   while TRUE do
  39.   begin
  40.     if CuantosSon(ParamStr(1)) < 1 then
  41.       ShellExecute(0,nil,PChar(ParamStr(1)),nil,nil,SW_SHOW);
  42.     // Aqui pones el retardo que quieras
  43.     Sleep(1000);
  44.   end;
  45. end.



Por ejemplo si queremos tener el bloc de notas siempre abierto:


delphi
  1. watchdog "C:\Windows\notepad.exe"




  • 0

#4 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 23 October 2010 - 04:12 PM

Podrías también cambiar la forma de capturar la ejecución de la aplicación.

Alguna vez elaboré este procedimiento:



delphi
  1. //Añadir al uses TLHelp32
  2.  
  3. function TForm1.procrunning: Boolean;
  4. var
  5.   Proceso : TProcessEntry32;
  6.   ProcessHandle : THandle;
  7.   Sproceso  : Boolean;
  8.   Nproceso : String;
  9. begin
  10.   Result := False;
  11.   Proceso.dwSize := SizeOf(TProcessEntry32);
  12.   ProcessHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  13.   if Process32First(ProcessHandle, Proceso) then
  14.   begin
  15.     Nproceso:= String(Proceso.szExeFile);
  16.     repeat Sproceso := Process32Next(ProcessHandle, Proceso);
  17.       Nproceso:= String(Proceso.szExeFile);
  18.       if Nproceso = 'elproceso.exe' then
  19.         Result := True;
  20.     until not Sproceso;
  21.   end;
  22.   CloseHandle(ProcessHandle);
  23. end;



El cual busca el proceso por su nombre y retorna un valor Falso o Verdadero.



Saludos!
  • 0

#5 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 23 October 2010 - 04:13 PM

seoane me ganaste por un click :D


Saludos!
  • 0

#6 agag4

agag4

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 posts
  • LocationMéxico

Posted 23 October 2010 - 05:00 PM

Gracias compañeros, voy a probar sus sugerencias....
  • 0

#7 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4111 posts
  • LocationMadrid - España

Posted 23 October 2010 - 06:43 PM

El uso de tlhelp32 o enumerar los procesos es muy eficaz y es una forma bastante fiable de localizar si un proceso está corriendo aunque depende del nombre de dicho proceso...

El uso del mutex no es descartable en este caso. Si lo queremos usar, yo crearía el mutex en el proceso externo destruyéndolo al terminarse.

En el proceso principal colocaría algo así:


delphi
  1. var
  2.   Mutex: THandle;
  3. begin
  4.     Mutex:= CreateMutex(nil, FALSE, 'PROG_EXTERNO');
  5.     if GetLastError = 0 then
  6.       ShellExecute(0, 'open', Proceso_externo, Argumentos, nil, SW_HIDE);
  7.     if Mutex<>0 then CloseHandle(Mutex);
  8.  
  9. end;



Este es el método que usé en una ocasión en un sistema de Vigilancia mutua entre dos procesos. El principal comprueba el mutex creado por el secundario, ese mutex se creaba con el nombre del principal que se pasa como parámetro al secundario usándolo para crear el mutex y arrancar al principal si no está en ejecución, comprobado esta vez usando tlhelp32 . El principal comprobaba el mutex de su propio nombre y si no existía ejecutaba al secundario.

Este sistema doble lo implementé porque el programa secundario lo usaba como vigilante de uno o dos procesos principales, de este modo podía tener una o dos copias del proceso vigilante secundario sin problemas.  *-)

Saludos.
  • 0

#8 agag4

agag4

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 posts
  • LocationMéxico

Posted 25 October 2010 - 08:31 AM

Gracias compañeros por sus sugerencias ya me funciono me fui por el método de felipe, probe los demas y tmb me funcionan, estuvo dificil la decisión por cual tomar  (y)
  • 0




IP.Board spam blocked by CleanTalk.