Page 1 of 2

Como saber el proceso en ejecución?

Posted: Wed Jul 28, 2010 3:15 pm
by jrestojeda
Hola a todos...
Estoy levantando los procesos en ejecución con la función GetTasks(), lo hace correctamente, pero con los datos que me regresa, no sé cual es el nombre del ejecutable asociado a ese proceso.

Ejemplo:
La función me regresa entre mis procesos esto:
"¡Bienvenido a Facebook en Español! - Windows Internet Explorer"

Yo al detectar la palabra "FACEBOOK" lo que quiero hacer es cerrar ese proceso. Pero si bien se que es detectada la palabra entre los procesos, no sé con esa información cual es el ejecutable. En este caso: "IEXPLORE.EXE"

Si lo abren con otro navegador detectaría la palabra pero el ejecutable sería el de ese otro navegador:
Ejemplo:
"¡Bienvenido a Facebook en Español (España)! - Mozilla Firefox" En este caso es "FIREFOX.EXE"

Lo que quiero hacer es con la llamada de TaskKill matar ese proceso, pero al no saber el nombre del PROCESO.exe no se a quien matar.

Dicho más simple, hay forma de saber para cada proceso que me regresa GetTasks() cual es el Ejecutable asociado en la lista de tareas??
Desde ya muchas gracias.
Saludos, Esteban.

Re: Como saber el proceso en ejecución?

Posted: Thu Jul 29, 2010 3:24 pm
by jrestojeda
:?: :?: :?: :roll:

Re: Como saber el proceso en ejecución?

Posted: Fri Jul 30, 2010 4:44 pm
by jrestojeda
:?: :?: :?: :roll:

Re: Como saber el proceso en ejecución?

Posted: Fri Jul 30, 2010 9:41 pm
by Antonio Linares
Eduardo,

la función GetTasks() usaba la función GetModuleFileName() que te devolvería exactamente lo que necesitas, lo que ocurre es que en 32 bits ya no funciona igual que en 16 bits. Es por esto que cambiamos GetTasks() para que devolviese el titulo de la ventana, que como bien explicas no sirve exactamente para lo que necesitas.

La solución es modificar la función GetTasks() (source\function\GetTasks.prg) y usar la función GetModuleFileNameEx():
http://msdn.microsoft.com/en-us/library ... S.85).aspx

Vamos a implementarla y te mostramos aqui su código.

Re: Como saber el proceso en ejecución?

Posted: Fri Jul 30, 2010 10:43 pm
by Antonio Linares
Necesitamos usar la función EnumChildWindows() asi que la implementamos:
http://msdn.microsoft.com/en-us/library ... S.85).aspx

Code: Select all

static PHB_ITEM pCodeBlock = NULL, pParam = NULL;

static BOOL CALLBACK EnumChildProc( HWND hWnd, LPARAM lParam )
{
   PHB_ITEM pNumber = hb_itemPutNL( NULL, ( LONG ) hWnd );

   if( pParam )
      hb_evalBlock( pCodeBlock, pNumber, pParam, NULL );
   else 
      hb_evalBlock1( pCodeBlock, pNumber );

   hb_itemRelease( pNumber );
      
   return TRUE;
}

HB_FUNC( ENUMCHILDWINDOWS )
{
   pCodeBlock = hb_param( 2, HB_IT_BLOCK );
   pParam = hb_param( 3, HB_IT_NUMERIC );
   hb_retl( EnumChildWindows( ( HWND ) hb_parnl( 1 ), EnumChildProc, hb_parnl( 2 ) ) );
   pCodeBlock = NULL;
   pParam = NULL;
}                          
 
Un ejemplo de uso de esta función sería:

Code: Select all

EnumChildWindows( GetDesktopWindow(), { | hWnd | AddTask( hWnd ) } )
 

Re: Como saber el proceso en ejecución?

Posted: Fri Jul 30, 2010 11:49 pm
by jrestojeda
Antonio...
Antes que nada, muchas gracias por la respuesta.

Creé un nuevo PRG al proyecto con lo siguiente:

Code: Select all

#pragma BEGINDUMP

#include <windows.h>
#include "hbapi.h"

static PHB_ITEM pCodeBlock = NULL, pParam = NULL;

BOOL CALLBACK EnumChildProc( HWND hWnd, LPARAM lParam )
{
   PHB_ITEM pNumber = hb_itemPutNL( NULL, ( LONG ) hWnd );

   if( pParam )
      hb_evalBlock( pCodeBlock, pNumber, pParam, NULL );
   else
      hb_evalBlock1( pCodeBlock, pNumber );

   hb_itemRelease( pNumber );

   return TRUE;
}

HB_FUNC( ENUMCHILDWINDOWS )
{
   pCodeBlock = hb_param( 2, HB_IT_BLOCK );
   pParam = hb_param( 3, HB_IT_NUMERIC );
   hb_retl( EnumChildWindows( ( HWND ) hb_parnl( 1 ), EnumChildProc, hb_parnl( 2 ) ) );
   pCodeBlock = NULL;
   pParam = NULL;
}

#pragma ENDDUMP
 
Por un lado me salen estos Warnings:

Code: Select all

Warning W8065 TASKN.prg 10: Call to function 'hb_itemPutNL' with no prototype in function EnumChildProc
Warning W8069 TASKN.prg 10: Nonportable pointer conversion in function EnumChildProc
Warning W8065 TASKN.prg 13: Call to function 'hb_evalBlock' with no prototype in function EnumChildProc
Warning W8065 TASKN.prg 15: Call to function 'hb_evalBlock1' with no prototype in function EnumChildProc
Warning W8065 TASKN.prg 17: Call to function 'hb_itemRelease' with no prototype in function EnumChildProc
Warning W8057 TASKN.prg 20: Parameter 'lParam' is never used in function EnumChildProc
 
Por otro lado al enlazar me dice que me falta la función ADDTASK()

Desde ya muchas gracias.
Saludos Esteban.

Re: Como saber el proceso en ejecución?

Posted: Sat Jul 31, 2010 3:58 am
by Daniel Garcia-Gil
Esteban

incluye este header

#include <hbapiitm.h>

a este warning no le prestes atencion

Warning W8057 TASKN.prg 20: Parameter 'lParam' is never used in function EnumChildProc

La funcion AddTask( ), tu mismo la implementas, supongo que la idea que presenta Antonio es que llenes un array con los handles de las ventanas hijas, ya teniendo esos valores podras disponer de ellos para el proceso que quieras

Re: Como saber el proceso en ejecución?

Posted: Sat Jul 31, 2010 5:08 am
by Antonio Linares
Esteban,

Aqui esta la función completa. En este ejemplo uso la nueva función MsgList() incluida en FWH 10.7:

Code: Select all

#include "FiveWin.ch"

#define GWL_HINSTANCE -6

static aTasks := {}

function Main()

   EnumChildWindows( GetDesktopWindow(), { | hWnd | AddTask( hWnd ) } )

   MsgList( ASort( aTasks ) )

return nil

function AddTask( hWnd )

   local cTaskName := GetWindowModuleFileName( hWnd )
   
   if AScan( aTasks, cTaskName ) == 0
      AAdd( aTasks, cTaskName )
   endif
   
return nil      

#pragma BEGINDUMP

#include <windows.h>
#include <psapi.h>
#include <hbapi.h>

HB_FUNC( GETWINDOWMODULEFILENAME )
{
   HWND hWnd = ( HWND ) hb_parnl( 1 );
   UINT processId = 0;
   DWORD dwLength = 1024;
   char buffer[ 1024 ];
   HMODULE hProcess;

   GetWindowThreadProcessId( hWnd, &processId );
   hProcess = OpenProcess( 1040, 0, processId );
   dwLength = GetModuleFileNameEx( hProcess, 0, buffer, dwLength );
   CloseHandle( hProcess );
   
   hb_retclen( buffer, dwLength );
}

#pragma ENDDUMP
 
Image

tags: EnumChildWindow GetTasks GetModuleFileName GetWindowThreadProcessId OpenProcess

Re: Como saber el proceso en ejecución?

Posted: Sat Jul 31, 2010 6:33 pm
by jrestojeda
Antonio...
Aún me falta la siguiente función al enlazar:

GetModuleFileNameExA

Desde ya muchas gracias.

Re: Como saber el proceso en ejecución?

Posted: Sun Aug 01, 2010 12:19 am
by Cgallegoa
Esteban,

Tienes que agregar el siguiente archivo de Borland:

\bcc582\lib\psdk\psapi.lib

Saludos,

Carlos Gallego

Re: Como saber el proceso en ejecución?

Posted: Sun Aug 01, 2010 2:25 am
by jrestojeda
Cgallegoa wrote:Esteban,

Tienes que agregar el siguiente archivo de Borland:

\bcc582\lib\psdk\psapi.lib

Saludos,

Carlos Gallego
Muchas gracias, seguimos avandando.
Con esto ya funciona el ejemplo de Antonio.

Re: Como saber el proceso en ejecución?

Posted: Sun Aug 01, 2010 3:57 pm
by jrestojeda
Hola a todos...
Sólo me falta el último detalle.

Por un lado tengo el array que me regresa la función GetTasks() Y por otro lado el array que me regresa la nueva función Addtask().
Cómo hago para relacionar estos dos Arrays?
Creo que necesitaría armar un array multidimensional, donde tenga en el mismo array lo que me regresa GetTasks() y lo que me regresa AddTask()
Con eso ya tendría la relación que hay entre los dos array y sabría que proceso que regresa AddTask() está asociado a cada cosa que regresa GetTasks()
Ejemplo:

Code: Select all

{"YouTube - YouTube de jreduojeda - Mozilla Firefox","C:\Archivos de programa\Mozilla Firefox\firefox.exe"        }
{"Yahoo! Argentina - Windows Internet Explorer"     ,"C:\Archivos de programa\Internet Explorer\iexplore.exe"     }
{"Visor de eventos - Messenger Plus!"               ,"C:\Archivos de programa\Windows Live\Messenger\msnmsgr.exe" }
{"Google - Mozilla Firefox"                         ,"C:\Archivos de programa\Mozilla Firefox\firefox.exe"        }
{"Windows Live Messenger"                           ,"C:\Archivos de programa\Windows Live\Messenger\msnmsgr.exe" } 
 
Si lograra obterner con las dos fucniones un array multidimensional de esta forma sería perfecto.
Creo que con las dos funciones que tengo, se podría armar una sola función que me arme este array que necesito. Yo realmente no le encontré la vuelta.
Si alguien me tira una mano, estaré sumamente agradecido.

Re: Como saber el proceso en ejecución?

Posted: Sun Aug 01, 2010 4:32 pm
by Antonio Linares
Eduardo,

Prueba asi:

Code: Select all

#include "FiveWin.ch"

#define GWL_HINSTANCE -6

static aTasks := {}

function Main()

   local aTask

   EnumChildWindows( GetDesktopWindow(), { | hWnd | AddTask( hWnd ) } )

   for each aTask in aTasks
      aTask = aTask[ 1 ] + ", " + aTask[ 2 ]
   next 
      
   MsgList( ASort( aTasks ), "Applications in use" )

return nil

function AddTask( hWnd )

   local cTaskName := GetWindowModuleFileName( hWnd )
   
   if AScan( aTasks, { | aTask | aTask[ 2 ] == cTaskName } ) == 0
      AAdd( aTasks, { GetWindowText( hWnd ), cTaskName } )
   endif
   
return nil     

#pragma BEGINDUMP

#include <windows.h>
#include <psapi.h>
#include <hbapi.h>

HB_FUNC( GETWINDOWMODULEFILENAME )
{
   HWND hWnd = ( HWND ) hb_parnl( 1 );
   UINT processId = 0;
   DWORD dwLength = 1024;
   char buffer[ 1024 ];
   HMODULE hProcess;

   GetWindowThreadProcessId( hWnd, &processId );
   hProcess = OpenProcess( 1040, 0, processId );
   dwLength = GetModuleFileNameEx( hProcess, 0, buffer, dwLength );
   CloseHandle( hProcess );
   
   hb_retclen( buffer, dwLength );
}

#pragma ENDDUMP 
 

Re: Como saber el proceso en ejecución?

Posted: Sun Aug 01, 2010 8:14 pm
by jrestojeda
Perfecto Antonio.
Muchas gracias.
Saludos, Esteban.

Re: Como saber el proceso en ejecución?

Posted: Thu Aug 05, 2010 8:19 pm
by acuellar
Esteban

Cómo habilito el Administrador de tareas nuevamente, ya que el TASK32 lo desabilitó.

Saludos

Adhemar