[Aplicación] WMI Info and Code Example

A raíz del post de WMI que escribí el otro día, empecé a crear una pequeña aplicación para obtener Información del Sistema con WMI.

He publicado la Aplicación en Code MSDN.

 

El funcionamiento de la aplicación es bastante sencillo. Al iniciar la aplicación, el Nombre del PC aparecerá reflejado en la caja de Texto de “Computer Name”, pero es un dato modificable.

Si pulsamos el Botón “GET”, va a obtener el Listado de Clases “consultables” a través de WMI, respecto del equipo indicado, quedando reflejadas en el combo.

Si tratamos de  consultar un equipo sobre el que no tenemos permisos, o un equipo apagado, la aplicación nos va a lanzar un aviso indicándolo.

Cada vez, que se seleccione una clase en el Combo, vamos a poder observar el listado de propiedades asociadas a la clase y los valores de cada una de ellas. Además, también aparecerán los métodos disponibles.

Para cada uno de los métodos disponibles, también se va a visualizar los parámetros de entrada y de salida asociados.

Por último, existe un botón el cual va a generar una clase de Ejemplo en C#, que podréis utilizar en vuestros proyectos para consultar los objetos de WMI.

Espero que os guste y sobretodo que os resulte útil.

Un saludo

[Tip] Exportación de Plantillas en VS

¿En cuantas ocasiones os habéis encontrado haciendo formularios muy similares, en distintos proyectos?

A mi al menos me ha pasado en muchas ocasiones.

Visual Studio, posee una herramienta para exportar plantillas predefinidas, como las que se muestran al agregar un nuevo elemento a un proyecto.

Podemos llevar a cabo dos tipos de Exportaciones:

– Por Elemento:

Como ejemplo podemos crear un formulario y añadirle una serie de controles comunes. El típico formulario de Alta de Registros con un botón guardar y otro de cancelar, y un panel con cajas de texto.

– Por Proyecto:

Podemos definir la estructura base que vamos a aplicar a nuestros proyectos, Carpetas, Clases con funcionalidades típicas, Splash Screen…

¿Que pasos son necesarios para definir una plantilla de un elemento?

En primer lugar, dentro de Visual Studio, vamos a crear un nuevo proyecto (aplica tanto a C# como a VB).

A continuación vamos a agregar un nuevo formulario, al que vamos a llamar formularioAlta.

Dentro de dicho botón vamos a incorporar los botones de Guardar y Cancelar.

Antes de poder realizar la exportación del formulario, será necesario que guardemos el proyecto.

A continuación a través del menú Archivo de Visual Studio, pulsaremos sobre la opción “Exportar Plantilla” y se abrirá un pequeño asistente para guiarnos en el proceso de Exportación.

El primer paso será para indicar si queremos realizar una exportación de una plantilla de Proyecto o de un elemento.

 

Después de indicar que vamos a exportar un Elemento, aparecerá un Árbol con los distintos elementos disponibles en nuestro proyecto, para que indiquemos los que van a ser exportados.

 

 

El siguiente paso, será indicar las referencias necesarias para el correcto funcionamiento de nuestra plantilla.

El último paso, nos va a permitir indicarle un nombre a la plantilla, así como una descripción y un icono para su posterior visualización.

Una vez que finalicemos con la exportación,  Gracias al check de “importación automática” Visual Studio, lo detectará y si pulsamos en “Agregar nuevo Elemento” a nuestra solución podremos ver la nueva Plantilla que hemos generado.

¿Que pasos son necesarios para definir una plantilla de un Formulario?

De los pasos indicados anteriormente serán necesarios el primero, en el que elegimos la forma de exportación, en este caso, será una Plantilla de Proyecto, y el último paso donde se definen el nombre y la descripción de la plantilla.

En este caso, para ver el resultado, cuando realicemos una exportación de un proyecto, será necesario crear un nuevo proyecto en Visual Studio, y dentro de las plantillas disponibles podremos encontrar la plantilla que hemos predefinido.

Espero que os sea de utilidad y si tenéis cualquier duda, podéis preguntarla por aquí o en Twitter.

 

Saludos

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.

Tip Rapido: Método Extensor

Bueno aquí va un mini-post.

Cuantas veces os habéis encontrado con:

if (a>=5 and a<=10)

Yo al menos recuerdo unas pocas.

Bueno aquí va el mini truco. Creamos una clase estática con un método extensor:

Code Snippet
  1. public static class ExtensionMethod
  2.  {
  3.    public  static bool Between(this int original, int menor, int mayor)
  4.      {
  5.          return (original >= menor && original <= mayor);
  6.      }
  7.  }

Ahora simplemente hacemos el using de la clase en donde queramos utilizarla y el IntelliSense de Visual Studio será capaz de asociar este método a nuestras variables de tipo int:

 

Code Snippet
  1. if (valorOriginal.Between(10, 20))
  2.             {
  3.  
  4.             }

Espero que os sea de utilidad.

 

Saludos.

[Channel9]Video Controles Personalizados

Bueno este post sirve para publicar el enlace de un pequeño video (mi primer video), en el que hablo acerca de la creación de Controles Personalizados dentro de Visual Studio, y el uso de algunos atributos en dichos controles.

 

Espero que os guste, y que me hagáis alguna crítica para futuros videos.

Se me olvidaba, lo mas importante dar las gracias a la gente de MSDN España por la publicación del video.

Un saludo

Buscar un Dato en un DataGridView

Lo primero es desearos un buen año 2011, a ver si nos da cosas mejoras que 2010!

Bueno esta entrada viene como consecuencia de repetidas preguntas acerca de una buscada de un valor en el control DataGridView.

Os voy a exponer en (VB  mañana cuelgo el código en c#) dos formas de hacerlo: la forma tradicional, y a través de LINQ:

Forma Tradicional
  1. Function Buscar(ByVal TextoABuscar As String, ByVal Columna As String, ByRef grid As DataGridView) As Boolean
  2.         Dim encontrado As Boolean = False
  3.         If TextoABuscar = String.Empty Then Return False
  4.         If grid.RowCount = 0 Then Return False
  5.         grid.ClearSelection()
  6.         If Columna = String.Empty Then
  7.             For Each row As DataGridViewRow In grid.Rows
  8.                 For Each cell As DataGridViewCell In row.Cells
  9.                     If cell.Value.ToString() = TextoABuscar Then
  10.                         row.Selected = True
  11.                         Return True
  12.                     End If
  13.                 Next
  14.             Next
  15.         Else
  16.             For Each row As DataGridViewRow In grid.Rows
  17.                 If row.IsNewRow Then Return False
  18.                 If row.Cells(Columna).Value.ToString() = TextoABuscar Then
  19.                     row.Selected = True
  20.                     Return True
  21.                 End If
  22.  
  23.             Next
  24.         End If
  25.         Return encontrado
  26.     End Function

Forma LINQ:

Forma LINQ
  1. Function BuscarLINQ(ByVal TextoABuscar As String, ByVal Columna As String, ByRef grid As DataGridView) As Boolean
  2.         Dim encontrado As Boolean = False
  3.         If TextoABuscar = String.Empty Then Return False
  4.         If grid.RowCount = 0 Then Return False
  5.         grid.ClearSelection()
  6.         If Columna = String.Empty Then
  7.             Dim obj As IEnumerable(Of DataGridViewRow) = From row As DataGridViewRow In grid.Rows.Cast(Of DataGridViewRow)()
  8.                       From celda As DataGridViewCell In row.Cells
  9.                         Where celda.OwningRow.Equals(row) And celda.Value = TextoABuscar
  10.                         Select row
  11.             If obj.Any() Then
  12.                 grid.Rows(obj.FirstOrDefault().Index).Selected = True
  13.             End If
  14.  
  15.         Else
  16.             Dim obj As IEnumerable(Of DataGridViewRow) = From row As DataGridViewRow In grid.Rows.Cast(Of DataGridViewRow)()
  17.                                              Where row.Cells(Columna).Value = TextoABuscar
  18.                         Select row
  19.             If obj.Any() Then
  20.                 grid.Rows(obj.FirstOrDefault().Index).Selected = True
  21.             End If
  22.  
  23.         End If
  24.         Return encontrado
  25.     End Function

 

En C#:

Forma Normal
  1. bool Buscar(string TextoABuscar,string Columna, DataGridView grid)
  2. {
  3.     bool encontrado=false;
  4.     if (TextoABuscar==string.Empty) return false;
  5.     if (grid.RowCount == 0 ) return false;
  6.     grid.ClearSelection();
  7.     if (Columna==string.Empty)
  8.     {
  9.         foreach (DataGridViewRow row in grid.Rows)
  10.         {
  11.             foreach (DataGridViewCell cell in row.Cells )
  12.                 if (cell.Value==TextoABuscar)
  13.                 {
  14.                     row.Selected = true;
  15.                     return true;
  16.                 }
  17.         }
  18.     }
  19.     else
  20.     {
  21.         foreach (DataGridViewRow row in grid.Rows)
  22.         {
  23.            
  24.                 if (row.Cells[Columna].Value==TextoABuscar)
  25.                 {
  26.                     row.Selected = true;
  27.                     return true;
  28.                 }
  29.         }
  30.     }
  31.     return encontrado;
  32. }

 

Forma LINQ
  1. bool BuscarLINQ(string TextoABuscar,string Columna, DataGridView grid)
  2.         {
  3.             bool encontrado=false;
  4.             if (TextoABuscar==string.Empty) return false;
  5.     if (grid.RowCount == 0 ) return false;
  6.     grid.ClearSelection();
  7.     if (Columna==string.Empty)
  8.     {
  9.         IEnumerable<DataGridViewRow> obj= (from DataGridViewRow row in grid.Rows.Cast<DataGridViewRow>()
  10.                                            from DataGridViewCell cells in row.Cells
  11.                                            where cells.OwningRow.Equals(row) && cells.Value==TextoABuscar
  12.                                            select row);
  13.         if (obj.Any())
  14.         {
  15.             grid.Rows[obj.FirstOrDefault().Index].Selected=true;
  16.             return true;
  17.         }
  18.  
  19.     }
  20.     else
  21.     {
  22.          IEnumerable<DataGridViewRow> obj= (from DataGridViewRow row in grid.Rows.Cast<DataGridViewRow>()
  23.                                            where row.Cells[Columna].Value == TextoABuscar
  24.                                            select row);
  25.         if (obj.Any())
  26.         {
  27.             grid.Rows[obj.FirstOrDefault().Index].Selected=true;
  28.             return true;
  29.         }
  30.             
  31.         }
  32. return encontrado;
  33.         
  34.  
  35.     }

La cabecera del método recibe como parámetros el valor a Buscar, la Columna a Buscar (si no se especifica buscará en todas las columnas), y el DataGridView donde se va a buscar.

 

Bueno espero que os sea de utilidad.

PD: Otra forma más que interesante de hacerla es como comenta Enrique Martínez en este enlace.