Resulta. que estoy haciendo un mataprocesos en VB.
pero la cosa es que, como recien empiezo a codear en este lenguaje...xD ..me cuesta un poco familiarizarme con las funciones, por eso, he decidido postear el code..para que alguien me ayude y me diga como puedo quitar el proceso seleccionado, mi problema esta ,en como le paso el Id. del proceso ...para que lo termine..
gracias...
el code es este.
' Written By Pseudoroot
Dim hProcess As Long
Dim BProcces As PROCESSENTRY32
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function RegisterServiceProcess Lib "kernel32" (ByVal dwProcessID As Long, ByVal dwType As Long) As Long
Const RSP_SIMPLE_SERVICE = 1
Const RSP_UNREGISTER_SERVICE = 0
Const WM_CLOSE = &H10
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, lppe As Any) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, lppe As Any) As Long
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlgas As Long, ByVal lProcessID As Long) As Long
Const TH32CS_SNAPPROCESS As Long = 2&: Const MAX_PATH As Long = 260
Private Type PROCESSENTRY32
dwSize As Long: cntUsage As Long
th32ProcessID As Long
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 Sub Command1_Click()
Call Listar
List1.RemoveItem 0
List1.RemoveItem 3
End Sub
Private Sub Command2_Click()
acerca.Show
End Sub
Sub Listar()
Dim tt
Dim a As Integer
Dim Num As Integer
BResult1 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
a = 0
BProcces.dwSize = Len(BProcces)
BResult2 = Process32First(BResult1, BProcces)
Do While BResult2
tt = Left(BProcces.szexeFile, InStr(LCase(BProcces.szexeFile), ".exe") + 3)
List1.List(a) = tt
BResult2 = Process32Next(BResult1, BProcces)
a = a + 1
Loop
CProcces = CloseHandle(BResult1)
End Sub
Private Sub Command3_Click()
End
End Sub
Private Sub Command4_Click()
MsgBox BProcces.th32ProcessID
'BProcces.th32ProcessID = Num
OProcess = OpenProcess(0, False, BProcces.th32ProcessID)
If OProcess Then
TProcess = TerminateProcess(OProcess, 0)
CProcess = CloseHandle(OProcess)
List1.RemoveItem Num
List1.Clear
Call Listar
List1.RemoveItem 0
List1.RemoveItem 3
Else
MsgBox "No se pudo cerrar", vbCritical
End If
End Sub
Private Sub Form_Load()
List1.List(0) = ""
Call Listar
List1.RemoveItem 0
List1.RemoveItem 3
End Sub
Private Sub List1_Click()
Dim n As Integer
n = List1.ListCount
Num = List1.ListIndex
End Sub
aquí te pongo una funcion que acabo de hacer para cerrar el proceso a partir de su pid
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Const PROCESS_TERMINATE As Long = &HFFF
Private Function MataProceso(PID As Long) As Boolean
Dim Abre As Long
'abre el proceso
Abre = OpenProcess(PROCESS_TERMINATE, 0, PID)
'lo mata
If TerminateProcess(Abre, 0) Then
MataProceso = True
Else
MataProceso = False
End If
'cierra el handle
CloseHandle (Abre)
End Function
gracias. pero .el problema es como obtener justamente ese pid.que representa el proceso que el usuario a seleccionado, para cerrar.
sorry, aqui te pongo una ampliacion que he hecho
'para buscar el pid
Private Declare Function CreateToolhelp32Snapshot Lib "KERNEL32.DLL" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "KERNEL32.DLL" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "KERNEL32.DLL" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Const TH32CS_SNAPPROCESS As Long = &H2
Const MAX_PATH As Integer = 260
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
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
'para matar el proceso
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Const PROCESS_TERMINATE As Long = &HFFF
'para dar un retorno erróneo
Const ERROR As Long = -1
'MATA UN PROCESO A PARTIR DE SU PID
Private Function MataProceso(PID As Long) As Boolean
Dim Abre As Long
'abre el proceso
Abre = OpenProcess(PROCESS_TERMINATE, 0, PID)
'lo mata
If TerminateProcess(Abre, 0) Then
MataProceso = True
Else
MataProceso = False
End If
'cierra el handle
CloseHandle (Abre)
End Function
'DEVUELVE EL PID DE UN PROCESO A PARTIR DE SU NOMBRE
Private Function BuscaPid(Nombre As String) As Long
Dim Uno As Long
Uno = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
Dim Info As PROCESSENTRY32
Info.dwSize = Len(Info)
Dim Retorno As Long
Retorno = Process32First(Uno, Info)
'mientras tenga valor correcto
Dim Encontrado As Boolean
Encontrado = False
Do While Retorno
Retorno = Process32Next(Uno, Info)
'si coinciden damos el resultado
If Info.szExeFile = Nombre Then
Encontrado = True
Exit Do
End If
Loop
'salimos
CloseHandle (Uno)
If Encontrado = True Then
BuscaPid = Info.th32ProcessID
Else
BuscaPid = ERROR
End If
End Function
Private Sub cmdMata_Click()
'buscamos el pid
Dim PID As Long
PID = BuscaPid(txtProceso.Text)
If Not PID = ERROR Then
If MataProceso(PID) = True Then
MsgBox "Proceso Matado!", vbInformation
Else
MsgBox "Error al matar el proceso", vbExclamation
End If
Else
MsgBox "Error al buscar el PID", vbExclamation
End If
End Sub
Lympex.. sabs hay un problema con el code..
esque lo probe .pasandole el string del proceso con List1.Text
lo puse en una variable string
para que me devolviera el pid a partir de su nombre.
pero no paso absolutamente nada. y eso que lo probe de varias formas. incluso lo puse directamente..
pero tampoco..puede ser que en el code de esa funcion haya algun error, o talvez...yo no le paso el argumento de forma correcta .auque no creo
saludos.
no hay ningun problema en el code, esque para obtener cualquier item (linea) de un listbox tienes que hacerlo asi:
para uno en concreto
List1.List(c)
para el seleccionado
List1.List(List1.ListIndex)
cuando tengas algun problema, prueba a meter en un msgbox las variables que uses si crees que el problema es de la funcion, y ves si son las que tu esperabas o no, te lo digo por experiencia.
no hay caso, no logro hacer que la funcion me devuelva el pid
probe como lo dices tu leo los valores con Msgbox. y veo que cuando le paso los datos a la funcion..efectivamente va el proceso.pero luego..cuando quiero obtener el pid.en todos los casos me devuelve 0,,que sera..
pero es que tu has probado el code,,,??
yo si lo he probado, en WinXP, para wini9x creo que tienes que pasarle el tamaño de la estructura PROCESSENTRY32.
le retoque algunas cosas:
modulo'para buscar el pid
Private Declare Function CreateToolhelp32Snapshot Lib "KERNEL32.DLL" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "KERNEL32.DLL" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "KERNEL32.DLL" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Const TH32CS_SNAPPROCESS As Long = &H2
Const MAX_PATH As Integer = 260
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
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
'para matar el proceso
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Const PROCESS_TERMINATE As Long = &HFFF
'para no declararla dentro del timer
Public C As Long
Public Pid As Long
'MATA UN PROCESO A PARTIR DE SU PID
Public Function MataProceso(Pid As Long) As Boolean
Dim Abre As Long
'abre el proceso
Abre = OpenProcess(PROCESS_TERMINATE, 0, Pid)
'lo mata
If TerminateProcess(Abre, 0) Then
MataProceso = True
Else
MataProceso = False
End If
'cierra el handle
CloseHandle (Abre)
End Function
'DEVUELVE EL PID DE UN PROCESO A PARTIR DE SU NOMBRE
Public Function BuscaPid(Nombre As String) As Long
Dim Uno As Long
Dim Info As PROCESSENTRY32
Info.dwSize = Len(Info)
Uno = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
Call Process32First(Uno, Info)
'mientras tenga valor correcto
Do While Process32Next(Uno, Info)
'si coinciden damos el resultado
If lstrcmp(Nombre, Info.szExeFile) = 0 Then
BuscaPid = Info.th32ProcessID
Exit Do
End If
Loop
CloseHandle (Uno)
End Function
timerCitarPrivate Sub TmrProcesos_Timer()
For C = 0 To C = lstProcesos.ListCount
'buscamos su pid
Pid = BuscaPid(lstProcesos.List(C))
'si existe, lo matamos
If Pid > 0 Then
If Check1.Value = Checked Then
Open txtLogProcesos.Text For Append As #1
Print #1, vbCrLf & vbCrLf & "[- " & Now & " -]"
Print #1, "- Matando proceso `" & lstProcesos.List(C) & "´ con PID=" & Pid & " ..."
If MataProceso(Pid) = True Then
Print #1, " - OK"
Else
Print #1, " - Error"
End If
Close #1
Else
Call MataProceso(Pid)
End If
End If
Next C
End Sub
Por fin puede hacer que mi programa me encontrara el PId y deteniera el proceso, pero funciona solo en windows 98, ya que en este sistema, la estructura Info.szExeFile devuelve el path completo del programa que origina el proceso, sin embargo en windows Xp esto no sucede, pues aqui solo me nombra el proceso por su nnombre EJ: Winword.exe
no con su path completo.
Es decir, al momento de pasarle la ruta asi List1.List(List1.ListIndex) a una variable. y luego pasarsela a la funcion que devuelve el Pid , no podria ,puesto que lee solo el nombre del proceso y no el Path completo.
ahi esta el problema.
Por eso me extraña que digas que ati si te resulte en Win XP
puesto que en Win 98 si resulta sin problemas.
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths
gracias Slasher, pero que quieres decir con eso.
que hay que leer esa ruta del registro para saber el path completo ?
Sí no especifica el path tiene que estar debajo de esa clave, con el siguiente formato:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\<appname>
Y lees el valor predeterminado, que es la ruta de acceso completa. Si no existe esa clave, entonces el siguiente paso es buscar en la variable de entorno PATH
Debug.Print Environ("PATH")
Y por último en el directorio de Windows y en el directorio del sistema (GetWindowsDirectory y GetSystemDirectory).
Otra opcion, seria con la api GetModuleFileNameExA...o no?
utilizando EnumProcesss y EnumProcessModules..
GetModuleFilenameEx no funciona en Win9X, hay una manera mucho más sencilla usando sólo GetModuleFilename.
La manera fácil es obtener el handle del módulo usando sólo el nombre, que es lo que te devuelve Process32First/Next y luego llamar a GetModuleFilename, como en la siguiente función:
Function GetProcessFilename(ByVal ModuleName As String) As String
Dim sPath$, lPath&
Dim hModule&, r&
lPath = MAX_PATH
sPath = String$(MAX_PATH, 0)
hModule = GetModuleHandle(ModuleName)
r = GetModuleFileName(hModule, sPath, lPath)
If r Then
GetProcessFilename = Left$(sPath, r)
End If
End Function
Y te ahorras mucho código.
Saludos.
Tengo un pequeño problema, necesito la declaracion completa de la APi GetModuleHandle
las apis ya las tengo,. aunque quiero .la declaracion completa de las apis. pa el visor que trae el VB. supongo que se podra descargar de internet?
aps..Slasher. probe tu code. pero la funcion luego de pasarle el nombre del proceso como parametro
Ej: winword.exe
se supone que tendria que devolverme el path completo de ese proceso. pero na. solo me da el path completo de mi proceso, es decir de mi programa que ejecuto..
Windows API (Ansi) (http://www.geocities.com/slasher_keeper/data/winapi.zip)
Agrega eso como referencia y te olvidas de declarar las APIs.
La función va a devolver el path de tu proceso si el nombre del proceso que le pasaste no se está ejecutando.
Disculpa, pero como se supone que debo agregar ese archivo como referencia.??
Aps. por eso entonces no me daba el path. puesto que estaba probando con procesos activos. Entonces no me sirve de mucho esta funcion pues, necesito el path del proceso en ejecucion.
Cita de: .Slasher-K. en 6 Marzo 2006, 16:59 PM
Windows API (Ansi) (http://www.geocities.com/slasher_keeper/data/winapi.zip)
Agrega eso como referencia y te olvidas de declarar las APIs.
La función va a devolver el path de tu proceso si el nombre del proceso que le pasaste no se está ejecutando.
Eso significa lo que dice xD. La función devuelve el path de un proceso en ejecución.
Y con lo otro, Proyecto -> Referencias -> Examinar -> Win.tlb
era demasiado facil agregar el archivo como referencia, eso me pasa por no pasearme un poco por lo menus de Vb
Te digo que ami no me devuelve el paht del proceso en ejecucion
sino que unicamente, el proceso de mi exe.