Por algunas razones largas de explicar, tuve que idear una forma de evitar que en una máquina con Windows Server 2003 se ejecutase la aplicación internet explorer pero solo en las sesiones Terminal Services, es decir en las sesiones abiertas directamente en el servidor se debía permitir ejecutar el internet explorer más no en las sesiones a través de Terminal Services. Mi solución fue escribir un pequeño programa utilizando las extensas facilidades de WMI. WMI es una poderosa herramienta aunque poco documentada, así que espero que esto les sea de utilidad. Para construir este ejemplo me apoye en el WMICodeCreator que es una aplicación de Microsoft que me permite generar código relacionado con WMI de forma automática.
Lo primero es crear un método donde hacer el query a WMI (líneas 12, 13), asociar el evento (línea 18) e iniciar el proceso de escucha (línea 21) . El query lo hice contra la clase Win32_ProcessStartTrace ya que esta clase me permite monitorear los procesos que se inician en el sistema operativo. Lo siguiente es determinar que solo quiero los procesos iexplore.exe que se inicien en sesiones terminal services, es decir todas las sesiones mayores a cero y para ello uso SessionID y ProcessName.
public WMIReceiveEvent() { try { string wmlquery = "SELECT * FROM Win32_ProcessStartTrace WHERE SessionID > 0 AND ProcessName = 'iexplore.exe'"; WqlEventQuery query = new WqlEventQuery(wmlquery); ManagementEventWatcher watcher = new ManagementEventWatcher(query); Console.WriteLine("Waiting for an event..."); watcher.EventArrived += new EventArrivedEventHandler(HandleEvent); // Start listening for events watcher.Start(); // Do something while waiting for events System.Threading.Thread.Sleep(-1); // Stop listening for events watcher.Stop(); return; } catch (ManagementException err) { Console.WriteLine("An error occurred while trying to receive an event: " + err.Message); } }
Luego debemos crear el método que responderá al evento. Como mi objetivo es evitar que el proceso iexplore.exe se ejecute lo que hago es detectar cuando se ejecuta y lo mato. Para matar el proceso también me valgo de WMI aunque esto se puede realizar de varias formas, solo lo uso para poderlo como ejemplo de uso de WMI. Se obtiene la instancia de la clase Win32_Process correspondiente al proceso iexplore.exe que se acaba de lanzar (línea 41) y luego hago uso del método Terminate de esta clase para matar al proceso (Líneas 44 y 47)
private void HandleEvent(object sender, EventArrivedEventArgs e) { Console.WriteLine(“Win32_ProcessStartTrace event occurred. :” + e.NewEvent["ProcessName"] ); try { ManagementObject classInstance = new ManagementObject(“root\CIMV2?, “Win32_Process.Handle=’” + e.NewEvent["ProcessID"] + “‘”, null); // Obtain in-parameters for the method ManagementBaseObject inParams = classInstance.GetMethodParameters(“Terminate”); // Execute the method and obtain the return values. ManagementBaseObject outParams = classInstance.InvokeMethod(“Terminate”, inParams, null); // List outParams Console.WriteLine(“ReturnValue: “ + outParams["ReturnValue"]); } catch (ManagementException err) { Console.WriteLine(“An error occurred while trying to execute the WMI method: “ + err.Message); } }
y por último el cuerpo principal del programa
public static void Main() { WMIReceiveEvent receiveEvent = new WMIReceiveEvent(); return; }
Como pueden observar es algo bastante simple y la mayoría del código fue generada automáticamente por WMICodeCreator. WMI es una herramienta muy poderosa y la aplicación WMICodeCreator es muy útil para curiosear en las múltiples cosas que se pueden hacer con WMI. Espero todo esto sea de utilidad.
Código fuente: AutoKilling.zip
Deja una respuesta