Alters

Remote Tools: Teoría de programación (III) - Procesos en VB.net

Buenas!

Estos días estoy hasta arriba, así que no podré actualizar el blog tanto como quisiera...

¡Eso no significa que no me acuerde de vosotros! :-P

Sigo aprendiendo cosas nuevas para poder compartirlas en este espacio (aunque, como digo, no tengo demasiado tiempo...)

En fin, vamos a lo que nos concierne: procesos con VB.net.





Algunos podéis pensar (y bien que hacéis) que se podría emular todo este asunto con un par de llamadas a una consola; pero, teniendo unas herramientas propias en vb.net... aunque lo veremos de las dos maneras.

La gestión de procesos puede ser peligrosa, ya que nos podemos "cargar" algún procesos importante del sistema y generar un "cuelgue".

  • Un vistazo rápido a los procesos:
¿Qué es un proceso? podríamos decir (de manera aproximada) que un proceso es una aplicación "persistente" en memoria.

Es decir, cuando abrimos una aplicación (navegador de internet, bloc de notas, editor de texto, ...) uno o varios procesos son creados. Éstos gestionan la memoria, los estados del proceso, y la ejecución en general.

Se podría decir que un proceso es el encargado de leer las instrucciones de la aplicación y ejecutarlas (y asegurarse de que se haga correctamente).

Si vamos a wikipedia, y hacemos un poco de "copy - paste", podríamos decir que:

A. S. Tanenbaum propone la analogía "Un científico computacional con mente culinaria hornea un pastel de cumpleaños para su hija; tiene la receta para un pastel de cumpleaños y una cocina bien equipada con todos los ingredientes necesarios, harina, huevo, azúcar, leche, etcétera." Situando cada parte de la analogía se puede decir que la receta representa el programa (el algoritmo), el científico computacional es el procesador y los ingredientes son las entradas del programa. El proceso es la actividad que consiste en que el científico computacional vaya leyendo la receta, obteniendo los ingredientes y horneando el pastel."

Por tanto, a estas alturas, podemos bien deducir que no puede existir una aplicación sin un proceso.

No obstante, al revés si se puede dar (se tiene que tener esto presente); o bien se puede dar el caso de que una aplicación tenga más de un proceso.

De este modo, siempre que queramos "erradicar" una aplicación, tendremos que ir a su proceso (o procesos) y quitarlos de nuestro sistema ("kill"). Del mismo modo, podemos querer lanzar un proceso (que puede abrir una aplicación o no), por lo que la gestión de procesos puede ser un gran arma en nuestro arsenal.

Para tratar procesos con VB.net (el caso que nos atañe), VB.net nos da la facilidad de usar una clase: "Process".

Esta clase tiene varios métodos que nos harán el manejo de procesos un poco más sencillo.

Veamos los métodos (y variables) más importantes:
  • Process.processName: retorna el nombre del proceso
  • Process.threads: retorna el conjunto de hilos que están corriendo en el proceso
  • Process.close(): libera los recursos asociados al proceso
  • Process.getProcessById(int32): obtiene el proceso con el id pasado
  • Process.getProcesses: obtiene todos los procesos
  • Process.getProcessesByName(String): obtiene todos los procesos que se llamen como el String pasado
  • Process.kill(): mata el proceso
  • Process.start(String): arranca el proceso con el nombre pasado
  • Process.start(String, String): arranca el proceso con el nombre (primer parámetro) usando los recursos especificados en el segundo parámetro.
En los siguientes puntos veremos cómo usar todos estos métodos y atributos.

  • Crear un proceso:
Como vemos arriba, basta con hacer un Process.start(String). Podemos hacerlo de varias maneras:

Process p = new Process()
p.start("miProceso.exe")

o bien, de manera compacta:

Process.start("miProceso.exe");

Hasta aquí fácil, ¿no?

Veamos ejemplos concretos:

Process.start("notepad.exe") 'abre notepad
Process.start("notepad.exe", "miFichero.txt") 'abre "miFichero.txt" en el bloc de notas

  • Listar procesos:
Podemos querer listar un proceso, para desarrollar una herramienta de control (por ejemplo). Para ello usaríamos los métodos de lista de procesos.

Aquí un par de ejemplos:

Dim procesos() as Process = Process.getProcessess()
'si queremos ver todos los procesos que son de Google chrome:
'Dim procesos() as Process = Process.getProcessess("chrome")

For i = 0 To procesos.Length - 1
    'cosas...
    'podríamos obtener el nombre con procesos(i).processName
    'podríamos ver el número de hilos con procesos(i).threads
Next

  • Matar procesos:
Usando el comando Process.kill(), combinado con Process.close(), podemos cerrar y "destruír" (casi) cualquier proceso activo en nuestra máquina.

Para este ejemplo, usaré parte del ejemplo anterior:

Dim procesos() as Process = Process.getProcessess("chrome")

For i = 0 To procesos.Length - 1
    procesos(i).kill()
    porcesos(i).close()
Next

  • Llamadas a consola con VB.net
Por si todo esto nos supiera a poco, sabed que desde VB.net podemos invocar una llamada directa a nuestra shell (cmd, en Windows).

Para ello basta con escribir el siguiente código:

Shell("C:\Windows\system32\calc.exe", AppWinStyle.NormalFocus)

Esto abriría una shell, y le pasaría el comando "C:\Windows\system32\calc.exe", que es la calculadora. Además, si os fijáis, podemos añadir un "estilo" a nuestra shell (incluso podemos decir que no se muestre ;-) )

  • Comandos para gestionar procesos con la conosola:
Dejo aquí una lista de comandos útiles para gestionar procesos desde consola:
  • tskill PID: mata el proceso identificado por el PID (Process ID) pasado como parámetro
  • start /prio process: inicia el proceso especificado en "process" con la prioridad "prio"
  • taskkill PID: lo mismo que tskill    
Como es usual en este tipo de entradas, me gustaría dejar claro que no debéis usar estos conocimientos para hacer "pillantrerías" ;-)

Ya sabéis, yo solo comparto mis conocimientos con vosotros, cómo lo uséis ¡depende únicamente de vosotros!

Con esto, terminamos la parte de procesos con VB.net, que usaremos más adelante en nuestra herramienta "Remote Tools".

Como siempre, ¡Hasta la próxima!

2 comentarios:

A Santos dijo...

Que tal buen dia,
He leido tu post y quiero aplicar algo como lo sig. en una app VB.NET:
'Cada vez que inicio sesion obtengo el ID del proceso actual, el ID lo guardare en una tabla SQL relacionandolo con el usuario y ID de usuario Actual.
Dim pid As Integer = Process.GetCurrentProcess.Id
Dim p As Process = Process.GetProcessById(pid)
If p Is Nothing Then Return
'Aqui pondre el codigo para verificar si ya ha iniciado sesion en alguna otra PC
'Si ya inicio Sesion preguntaria si desea terminar el programa en la otra PC.
'Algo como lo sig. pero me arroja un error, creo debedio a los permisos de admin ausentes en la otra PC.
Shell("taskkill/s 10.222.56.68/PID 12960", AppWinStyle.NormalFocus)

Alguna idea de como resolver esto?

David O. Solé González dijo...

Buenos días A Santos.
Sí, me da que el problema te va a venir por los permisos. Desde "Shell" podrás cerrar procesos locales, pero no en red.

Si vas a tener una tabla SQL, y en ambas máquinas (digamos "PC1", y "PC2") vas a tener el mismo programa corriendo, puedes añadir algún campo a una tabla de la base de datos, algo así como una tabla de peticiones.

Con esto, puedes crear un canal de comunicación entre "PC1" y "PC2"; digamos que en la tabla guardas el emisor ("PC1"), el receptor ("PC2"), el mensaje ("Cerrar tarea"), y el estado ("Activo").

Por otra parte, en VB.NET es fácil gestionar un timer, y en el evento "onTick" simplemente preguntar... "¿Tengo algún mensaje?" y al encontrar "Cerrar tarea", la máquina local sí sería capaz de ejecutar "taskkill"!


Un saludo y gracias por el comentario!

Publicar un comentario