Utilización de WMI en VS 2010

¿Qué es WMI?

WMI son las siglas de “Windows Management Instrumentation” (Instrumentación de la Administración de Windows.)

WMI nos va a permitir obtener información representativa de grandes partes de un Ordenador como pueden ser el SO, Aplicaciones instaladas, o incluso el Hardware de la maquina.

WMI no solo aporta datos del ordenador donde lo estamos utilizando, también podemos acceder de manera remota a otros ordenadores.

¿Cómo podemos empezar a utilizar WMI en nuestros proyectos?

Para poder utilizar WMI, necesitamos agregar a nuestro proyecto la referencia “System.Management”

 

 

A continuación será necesario incluir el namespace en la clase donde vayamos a trabajar con WMI:

using System.Management;

o
imports System.Management

El Framework nos va a aportar las siguientes clases para poder trabajar con WMI:

ManagementObjectSearcher:

Esta clase se va a encargar de realizar una consulta determinada a WMI, y devolver un conjunto de ManagementObject’s.

   1: ManagementObjectSearcher searcher = 

   2:     new ManagementObjectSearcher("Select * from Win32_Desktop");

   3: var query = from ManagementObject managedObject

   4:  in searcher.Get().Cast<ManagementObject>()

   5:             select managedObject;

A través del constructor de la clase, indicamos la sentencia WMI que vamos a utilizar (más adelante veremos mas información sobre ellas).

La sentencia que utilizo en el ejemplo es una Query de LINQ to Objects sobre el método Get del objeto que estamos utilizando.

El método GET va a devolver una colección objetos del tipo ManagementObjectCollection.

ManagementObject:

La clase ManagementObject va a almacenar una serie de datos relativos cada registro de una consulta sobre WMI.

Los datos que vamos a poder consultar son los siguientes:

– Scope:

Es el ámbito de realización de la Administración. Esta propiedad es del Tipo ManagementScope.

– Path:

Es la ruta relativa al objeto dentro de la consulta WMI.

– Options:

Aporta información adicional acerca del objeto.

– ClassPath:

Es la ruta relativa del Objeto.

– Properties:

Son las características de cada uno de nuestros Objetos. Un poco mas adelante se verá en la clase PropertyData.

– SystemProperties:

Propiedades del sistema relativas a la consulta que hemos realizado.

– Qualifiers

Van a proporcionar mas información acerca de nuestro Objeto.

PropertyData

Esta clase nos va a indicar información relativa a cada propiedad de una consulta realizada.

Lo más interesante de está clase es que nos va a indicar el Nombre (Name) y el valor (Value) concreto de una propiedad. Por ejemplo:

Para la clase “Win32_Desktop” que nos da información relativa a la pantalla, una propiedad es: “ScreenServerActive”, que indicará si el SalvaPantallas está activado o no.

   1: ManagementObjectSearcher searcher = 

   2:     new ManagementObjectSearcher("Select * from Win32_Desktop");

   3:  

   4:  

   5: var query = from ManagementObject managedObject 

   6:                 in searcher.Get().Cast<ManagementObject>()

   7:             from PropertyData prop 

   8:                 in managedObject.Properties.Cast<PropertyData>()

   9:  

  10:             select prop;

El código que he puesto en el bloque nos va a devolver una lista de las propiedades de “todos” los objetos existentes que respondan a la consulta.

 

¿Cómo podemos empezar a utilizar WMI para conectarnos a otros equipos?

Hasta el momento hemos visto la posibilidad de obtener información del equipo “Local”, pero, ¿y si necesitamos información de un equipo en red?.

Lo que hemos explicado anteriormente es totalmente aplicable para obtener información de un equipo remoto, pero necesitamos indicarle de alguna manera el equipo cuya información queremos consultar.

   1: ManagementScope scope =

   2: new ManagementScope(

   3:     @"\NBEQUIPorootcimv2");

   4: scope.Connect();

   5: ManagementObjectSearcher searcher =

   6:  new ManagementObjectSearcher(scope, 

   7: new ObjectQuery("Select * from Win32_Desktop"));

   8:  var query = from ManagementObject managedObject 

   9:              in searcher.Get().Cast<ManagementObject>()

  10:              from PropertyData prop 

  11:              in managedObject.Properties.Cast<PropertyData>()

  12:  

  13:             select prop;

Para indicarle a la consulta donde tiene que ejecutarse necesitamos un objeto de tipo ManagementScope.

ManagementScope:

Esta clase va a permitir definir el ámbito de una consulta.

El constructor de la clase, nos va a permitir indicar el Nombre del equipo a consultar.

¿Qué datos podemos obtener utilizando WMI?

Gracias a la utilización de los objetos antes mencionados, podemos obtener información, tanto de nuestro ordenador, como de una maquina remota.

Pero, ¿Dónde puedo saber que datos puedo consultar con WMI?. La respuesta es corta: MSDN.

En el enlace, nos vamos a encontrar diversas categorías de información que podemos obtener a través de WMI.

¿Hasta aquí hemos llegado con WMI?

No. WMI no solo nos permite visualizar información, también nos permite hacer algunas tareas propias de la administración, como podrían ser, copia de ficheros, iniciar un Servicio, parar una impresión…

Algunas de las clases que aparecen en el enlace que os indicaba anteriormente a parte de tener propiedades, también poseen ciertos métodos que nos permite realizar tareas administrativas.

Para poder obtener los métodos de un objeto, tenemos que apoyarnos en la clase: ManagementClass.

ManagementClass

Esta clase es similar a ManagementObject, y nos permite obtener todo el conjunto de propiedades y métodos, simplemente especificando en el nombre de la consulta.

   1: ManagementClass clase = 

   2:        new ManagementClass("Win32_Process");

Puesto que anteriormente estabamos trabajando objetos de tipo ManagementObjet, podríamos utilizar el siguiente código:

   1: ManagementObjectSearcher searcher =

   2:  new ManagementObjectSearcher("Select * from Win32_Process");

   3:  var query = from ManagementObject managedObject 

   4:              in searcher.Get().Cast<ManagementObject>()

   5:              from PropertyData prop 

   6:              in managedObject.Properties.Cast<PropertyData>()

   7:  

   8:              select managedObject;

   9:  ManagementObjectSearcher s = new ManagementObjectSearcher();

  10:  

  11:  ManagementClass clase = 

  12:   new ManagementClass(query.FirstOrDefault().ClassPath);

Con el snippet anterior, obtendríamos el primer objeto devuelto por la consulta WMI.

Una vez que tenemos nuestro objeto, podemos consultar las Propiedades, o los métodos a través de las propìedades de la clase.

La propiedad Metods: va a devolver un objeto de tipo MethodDataCollection que es un conjunto de objetos del tipo MethoData.

MethodData

Este objeto va a almacenar las propiedades relativas a cada método:

– Nombre

– Parámetros de Entrada

– Parámetros de Salida

– Origen

– Calificadores

Si conocemos el método que queremos ejecutar, que parámetros necesita para ser ejecutado y la clase a la que pertenece, podemos ejecutarlo:

   1: clase.InvokeMethod("Create", 

   2: new object[] { "calc.exe" });

 

El método InvokeMethod, va a ejecutar el método que recibe como primer parámetro, utilizando el array de objetos que se le envía como argumentos para la ejecución.

El ejemplo es muy sencillo, lo que hace sobre la clase “Process” es ejecutar la calculadora de Windows.

 

Conclusiones

WMI nos va a permitir “jugar” y “cacharrear” con la información del Sistema así como hacer ciertas operaciones.

Mientras redactaba este artículo me tope con una herramienta que me pareció muy interesante. Se llama WMI Code Creator. Os animo a que la descarguéis y juguéis un poco con WMI y el código generado. Os aviso que la parte de código en C# contiene algunos errores al generar los ejemplos.

 

Bibliografía

La base fundamental de este artículo es la documentación MSDN:

http://msdn.microsoft.com/en-us/library/aa394582(VS.85).aspx

 

Espero que os guste.

5 comentarios sobre “Utilización de WMI en VS 2010”

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *