PDA

Ver la Versión Completa : Detectar nuevos procesos en windows


DanForever
05-04-2006, 12:49:08
En la situacion de ke mi aplicacion está minimizada, y el usuario inicia una , ¿como puedo hacer para detectar cuándo se ha iniciado el proceso, y saber qué proceso es el que se ha iniciado?

Neftali [Germán.Estévez]
05-04-2006, 13:12:38
Puedes encontrar (haz una búsqueda en los foros) el código para obtener la lista de procesos que hay en marcha; Es cuestión de ir tomando esa lista cada cierto tiempo y mirando las diferencias.

Bicho
05-04-2006, 13:22:32
Hola,

puedes crear una captura con los procesos activos en un intervalo de tiempo (p.ej cada minuto), obtienes una lista con los procesos abiertos, al minutos, haces una segunda captura de los procesos activos y comparas las dos listas, podrás saber si hay procesos nuevos o procesos terminados.

Función para obtenerlos procesos activos

Añade 'TLHelp32' en el uses de tu form
Pon una TListBox (ListBox1) y un TButton (Button1) en tu form
Pon este código en el OnClick de Button1:

procedure TForm1.Button1Click(Sender: TObject);

function SacaExe(MangoW:HWND):string;
{Obtiene el EXE de una tarea}
{get EXE of a task}
var
Datos :TProcessEntry32;
hID : DWord;
Snap : Integer;
begin
GetWindowThreadProcessId(MangoW,@hID);
Snap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
try
Datos.dwSize:=SizeOf(Datos);
if(Process32First(Snap,Datos))then
begin
repeat
if Datos.th32ProcessID=hID then
begin
Result:=StrPas(Datos.szExeFile);
Break;
end;
until not(Process32Next(Snap,Datos));
end;
finally
Windows.CloseHandle(Snap);
end;
end;


function ObtieneVentanas(Mango: HWND;
Nada: Pointer): Boolean; stdcall;
var
sTemp:string;
begin
Result := True;
{Mango es el handle de la tarea encontrada}
{Añadimos el .EXE si no está ya añadido...}
sTemp:=SacaExe(Mango);
with Form1.ListBox1.Items do
if IndexOf(sTemp) = - 1 then Add(sTemp);
end;

begin
EnumWindows( @ObtieneVentanas, 0 );
end;


Espero te sirva de ayuda.

Saludos

dec
07-04-2006, 23:31:34
Hola,

Los Servicios de Windows son un mundo entero. En la ayuda que acompaña a Delphi, el SDK de Wind32 describe las diferentes funciones para tratar con ellos. Pero, nosotros también contamos con la librería Jedi JCL (http://sourceforge.net/projects/jcl/), no confundir con la Jedi VCL (http://jvcl.sourceforge.net/). En la Jedi JCL hay no pocas unidades que pueden sernos útiles en un momento dado, y, entre otras, se encuentra la unidad "JclSvcCtrl.pas", la cual hace uso de las funciones de la API de Windows para trabajar con sus Servicios, e incluso, yendo más allá, cuenta con clases para tratar a los Servicios como si de objetos se trataran.

Por ejemplo, el siguiente código está adaptado (robado, debía decir, o poco menos) de la mencionada unidad de la Jedi JCL, y, como se ve, con el mismo conocermos todos los Servicios conque Windows cuente. De todos modos el código no valdrá de nada si no se comprende (ni tampoco se podrá ir más allá o más acá del mismo), y, como digo, si se tiene interés en esto último, a darse una vuelta por el SDK de Win32 y por la unidad "JclSvcCtrl.pas" de la Jedi JCL, para empezar a abrir boca. He dicho. ;)


uses
Dialogs, WinSvc;

procedure TfrmPrincipal.Button1Click(Sender: TObject);
var
i: integer;
continuar: boolean;
cbBufSize: Pointer;
lpServices: PEnumServiceStatus;
hSCManager, pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD;
begin
hSCManager := OpenSCManager('', nil, SC_MANAGER_ENUMERATE_SERVICE);
if (hSCManager <> 0) then
begin
lpResumeHandle := 0; // Esta variable ha de inicializarse a cero
try
cbBufSize := nil;
pcbBytesNeeded := SizeOf(lpServices);
repeat
ReallocMem(cbBufSize, pcbBytesNeeded);
continuar := EnumServicesStatus(hSCManager, SERVICE_TYPE_ALL, SERVICE_STATE_ALL,
PEnumServiceStatus(cbBufSize)^, pcbBytesNeeded, pcbBytesNeeded,
lpServicesReturned, lpResumeHandle);
until continuar or (GetLastError <> ERROR_MORE_DATA);

lpServices := cbBufSize;
for i := 0 to lpServicesReturned - 1 do
begin
{ Lo siguiente ya a nuestra disposición aquí

lpServices^.lpServiceName
lpServices^.lpDisplayName
lpServices^.ServiceStatus.dwServiceType
lpServices^.ServiceStatus.dwCurrentState
lpServices^.ServiceStatus.dwControlsAccepted
lpServices^.ServiceStatus.dwWin32ExitCode
lpServices^.ServiceStatus.dwServiceSpecificExitCode
lpServices^.ServiceStatus.dwCheckPoint
lpServices^.ServiceStatus.dwWaitHint
}
Inc(lpServices);
end;
finally
FreeMem(cbBufSize);
end;
end;
end;

DanForever
24-04-2006, 08:21:50
;) Gracias por vuestra ayuda! Me habeis dado la ayuda que necesitaba, aunque... :confused:¿qué intervalo podría poner en el timer, para que parezca casi un evento más de la aplicación (que se ejecutara casi al instante de abrir otra aplicación)?

dec
02-10-2006, 17:34:10
Hola,

Esto quedó sin respuesta en su momento y tú tampoco pareces haber ahondado en ello:


¿qué intervalo podría poner en el timer, para que parezca casi un evento más de la aplicación (que se ejecutara casi al instante de abrir otra aplicación)?


Yo creo que es cuestión de que hagas unas pruebas... supongo que con un intervalo de 100 ó 200 milisegundos ya sería más que suficiente.