Obtener ID para OpenProcess

Iniciado por Gorky, 23 Mayo 2006, 14:51 PM

0 Miembros y 1 Visitante están viendo este tema.

Gorky

Buenas foreros. Despues de esta pausa vamos a tomar nuestro camino de nuevo.

Necesito hallar el ID de un proceso para usarlo en los parametros del OpenProcess. El proceso ya esta corriendo, no lo ejecuto yo, es decir, no puedo sacar el ID a partir del valor de vuelto por Shell(). De este proceso se su nombre con el que esta corriendo y su path. Intuyo que tal vez podria hacerlo con EnumProcesses y comparando con los nombres pero si no me equivoco esto te devuelve una matriz de ID y los nombres no aparecen. Espero que me podais sacar de mi problema. Gracias.

Eternal Idol

Si usas EnumProcesses de la PSAPI.dll tambien podes usar GetModuleBaseName para obtener el nombre de un proceso (esta en la misma DLL).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Gorky

Eternal Idol no se porque pero sabia que ibas a contestar tu.  ;)
No es que yo quiera usar la funcion EnumProcesses sino que creo que para solucionar mi problema se puede tomar ese camino. Lo que quiero es tomar el camino mas conveniente.
Paso a detallar desde el principio el problema para intentar encontrar la solucion optima:
Pretendo finalizar un proceso. Para eso hago uso de la funcion ExitProcess. Esta me pide un ExitCode que obtengo mediante GetExitCodeProcess. A su vez esta funcion necesita un handle que saco de OpenProcess. Y esta ultima necesita un identificador del proceso que no se como obtener.
De manera que tengo el principio del algoritmo (el nombre o path del proceso) y el final (ExitProcess(GetExitCodeProcess(OpenProcess))). Ahora me hace falta la parte central.

Cita de: Eternal Idol en 23 Mayo 2006, 18:01 PM
Si usas EnumProcesses de la PSAPI.dll tambien podes usar GetModuleBaseName para obtener el nombre de un proceso (esta en la misma DLL).

Se que no hay cosa que joda mas que dar una respuesta y que la ignoren. No es este el caso.
Si sigo el camino que has dicho se supone que deberia enumerarlos con EnumProcesses, obtener el path con GetModuleBaseName de cada proceso y comparar. Cierto?
Y por ultimo otra pregunta: sabes que diferencia hay entre GetModuleBaseName y GetModuleFileName?

Eternal Idol

Cita de: Gorky en 24 Mayo 2006, 09:03 AMPretendo finalizar un proceso. Para eso hago uso de la funcion ExitProcess.

ExitProcess termina el proceso ACTUAL, tendrias que inyectar codigo en el otro proceso que ejecutara esa funcion. Sino podes usar TerminateProcess.

Cita de: Gorky en 24 Mayo 2006, 09:03 AMSi sigo el camino que has dicho se supone que deberia enumerarlos con EnumProcesses, obtener el path con GetModuleBaseName de cada proceso y comparar. Cierto?
Y por ultimo otra pregunta: sabes que diferencia hay entre GetModuleBaseName y GetModuleFileName?

Si, la logica seria hacer eso. Y la diferencia es que basicamente estan en dos modulos diferentes, por eso comente lo de la PSAPI.dll, el GetModuleFileName esta en Kernel32.dll ...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Dyablo Poeta

Hola
Bueno si lo que buskas es capturar el Pid de un proceso activo la mejor y mas rapida manera es utiliando la api CreateToolhelp32Snapshot la cual genera una sctructura que entre tantas cosas esta el Pid, ya con el peudes usar el Pid en el openprocess para que t devuelva el handle que necesitas, te adjunto un ejemplo del uso de la api:

CitarConst TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
Const MAX_PATH As Integer = 260
Private Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long 'devuelve el pid del proceso indicado
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szExeFile As String * MAX_PATH
End Type
Private Declare Function CreateToolhelp32Snapshot Lib "Kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Function Process32First Lib "Kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "Kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Sub CloseHandle Lib "Kernel32" (ByVal hPass As Long)
Private Sub Form_Load()

    Dim hSnapShot As Long, uProcess As PROCESSENTRY32
    'Takes a snapshot of the processes and the heaps, modules, and threads used by the processes
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)
    'set the length of our ProcessEntry-type
    uProcess.dwSize = Len(uProcess)
    'Retrieve information about the first process encountered in our system snapshot
    r = Process32First(hSnapShot, uProcess)
    'set graphics mode to persistent
    Me.AutoRedraw = True
    Do While r
        Me.Print Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0))
        'Retrieve information about the next process recorded in our system snapshot
        r = Process32Next(hSnapShot, uProcess)
    Loop
    'close our snapshot handle
    CloseHandle hSnapShot
End Sub
Este Ejemplo esta en el Programa Api Guide, de todas maneras si tubieras problemas me escribes al privado para enviarte una version que tengo ya lista, la cual basta con indicar que proceso deseamos sakarle el pid y t lo devuelve.
Saludos

Gorky

Dyablo Poeta estas seguro que eso funciona? No lo he llegado a probar pero lee la informacion que da Microsoft a cerca de las bibliotecas ToolHelp32 y PSAPI en http://support.microsoft.com/default.aspx?scid=kb%3Bes%3B175030

CitarUsar la biblioteca ToolHelp32 para enumerar procesos
En primer lugar usaremos la solución con ToolHelp32. Las funciones de ToolHelp32 que residen en el archivo KERNEL32.dll son estándar de la API. Observe que estas API no están disponibles en Windows NT 4.0.

CitarUsar la biblioteca PSAPI para enumerar procesos
En la solución de Windows NT para crear una lista de procesos se usan las funciones de PSAPI que reside en PSAPI.dll.

Kizar

Usa CreateToolhelp32Snapshot y el codigo que a dicho Dyablo Poeta.
Salu2

Dyablo Poeta

bueno te adjunto un codigo que lo tengo listo para buskar cualkier proceso partiendo de su nombre, el ejemplo te lo envio con nombre de proceso explorer.exe , ahi podras ver como sacar el pid y el process handle, de pasada usar el terminateprocess para cerrar el proceso.
Descargalo de http://rapidshare.de/files/21360810/buscarpid.rar.html
Saludos

pd.- lo adjunte a rapidshare pues no encontre la opcion para adjuntar achivos.

Gorky

Gracias Dyablo Poeta por el codigo pero no ignoreis lo que he dicho en el post anterior. Mas que nada es por salir de la duda de las incompatibilidades.

Dyablo Poeta

Sobre el problema de incompatibilidades al parecer es cuando el programa se ejecuta en un windows nt 4 en ese caso  el programa utilizando CreateToolhelp32Snapshot  no funcionaria, y forzosamente deberias usar PSAPI para enumerar los procesos, pero por experiecnia propia ese cod que t he mandado funciona correctamente en win 98, win 2k, win xp, win 2003, a por cierto  al usar CreateToolhelp32Snapshot para un windows 98 necesitaras poner todo el patch donde reside el proceso que deseas terminar.
Saludos