• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

inginheiiro

[Windows] Windows Management Instrumentation (WMI)

6 mensagens neste tópico

Boas.

Tenho visto varios tópicos neste fórum que abordam questões como :

  • monitorizar a rede/cpu
  • extrair informação de maquinas remotas
  • saber números de serie de dispositivos
  • etc.

Basicamente estas questões são respondidas através do uso da API (WMI), que vem integrada com o windows.

O WMI pode ser invocado por qualquer linguagem já que é um serviço COM.

Podem ver mais informações em http://msdn2.microsoft.com/en-us/library/aa394582.aspx

As potencialidades deste "serviço" são imensas :).

Posso-vos dizer que software como o SiSandra ou outro qualquer de benchmark faz um uso extensivo das potencialidades do WMI.

Hoje trago-vos uma forma de desenvolver software facilmente, com um grau de abstracção à forma como se usa o WMI ou seja: resolvi disponibilizar mais uma das minhas APIs para uso público.

Pontos a ter em consideração:

  • A API uso da framework CarlosAG.ExcelWriter para exportar dados em formato xls.
  • A API permite apenas efectuar queries ao serviço WMI de uma forma simplificada.
  • A API disponibiliza um conjunto (não a totalidade) de classes Win32 (WMI Classes) previamente identificadas.
  • A API foi desenvolvida para a framework 1.1 da MS. É possivel usá-la em vb6, c++, vbs, etc (é necessario ainda ter a framework 1.1 instalada) pois está desenvolvida com assinaturas para objectos COM.
  • Não vou aqui descrever o funcionamento do WMI, para isso têm o link da MS que está exposto acima com toda a informação. O objectivo deste tutorial é sim descrever o uso do WMI através da framework que irei disponibilizar.

Visto isto, passemos à acção. :)

Suponham que desejam criar uma aplicação que retorne todos os dados do vosso processador.

É bastante simples:

  1. Criem um novo projecto no Visual Studio
  2. Façam referência à API que está no meu site.
  3. Façam uma query ao hardware do computador.

using System.Collections;
using System;
using WMI;

namespace CpuTest
{	
class Class1
{
	[sTAThread]
	static void Main(string[] args)
	{
		WMI.Kernel w = new WMI.Kernel();		
		try
		{
			w.Connect();  //Conecta-se
			Hashtable [] result = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.Hardware.Win32_Processor));

			foreach(Hashtable h in result ){
				foreach(string key in h.Keys)
					Console.WriteLine(string.Format(" Campo {0} -> {1}",key,h[key].ToString()));					
			}

		} catch (Exception ex){
			Console.WriteLine(ex.Message);
		}
	}
}
}

O w.Connect(); connecta-se ao serviço WMI disponivel no vosso computador.

O w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.Hardware.Win32_Processor)); efectua uma query ao serviço WMI, à classe Win32_Processor.

Esta função retorna um array de Hashtables, onde cada Hashtable contém o Campo(key)->Valor.

Por exemplo, se quisessem só saber qual era o fabricante do vosso CPU fariam algo do genero:

w.ExecuteWmiQuery(string.Format("Select Manufacturer from {0}",WMI.Classes.Hardware.Win32_Processor));

Como disse acima, existe uma série de classes pré definidas e separadas na API que desenvolvi.

Podem ser vistas na classe WMI.Classes

Estão divididas nas categorias:

  • Developer
  • UserAccount
  • Network
  • SystemInformation
  • Memory
  • Storage
  • Hardware

OK, suponham que desejam monitorizar a memoria de uma máquina que não a vossa.

Continua a ser simples :)

using System.Globalization;
using System.Collections;
using System;
using WMI;

namespace CpuTest
{	
class Class1
{	
	[sTAThread]
	static void Main(string[] args)
	{

		WMI.Kernel w = new WMI.Kernel("192.168.50.199","administrator","password");
		try
		{
			w.Connect();  //Conecta-se
			Hashtable [] result = w.ExecuteWmiQuery(string.Format("Select * from {0} ",WMI.Classes.Developer.Win32_PerfRawData_PerfOS_Memory));

			foreach(Hashtable h in result ){
					ulong  Mem   = (ulong)Convert.ToInt64(h["AvailableMBytes"]);											
					Console.WriteLine("Memory Usage"+Mem   +" MB");					
			}

		} catch (Exception ex){
			Console.WriteLine(ex.Message);
		}
	}
}
}

Ok, agora suponhamos que queria ver todo o software instalado numa maquina, e criar uma folha Excel com isso.

Queriamos também escrever os dados da nossa BIOS.

Continua a ser simples :)

using System.Globalization;
using System.Collections;
using System;
using WMI;

namespace CpuTest
{	
class Class1
{	
	[sTAThread]
	static void Main(string[] args)
	{

		WMI.Kernel w = new WMI.Kernel("192.168.50.199","administrator","password");
		try
		{
			w.Connect();  //Conecta-se
			w.OpenXLSBook("Software Instalado");  // Abre uma nova folhas
			Hashtable [] na = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.SystemInformation.Win32_Product));

			// Cria um cabeçalho baseado nas propriedades retornadas.
			w.exportHeaderToXLS("Software",na);


			// Exporta os dados para a folha excel
			foreach (System.Collections.Hashtable a in na)
				w.exportDataToXLS(a);


			//Query à BIOS				
			na = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.Hardware.Win32_BIOS));

			// Cria um cabeçalho baseado nas propriedades retornadas.
			w.exportHeaderToXLS("BIOS",na);

			// Exporta os dados para a folha excel
			foreach (System.Collections.Hashtable a in na)
				w.exportDataToXLS(a);			

			//Grava a folha
			w.CloseXLSBook("doc.xls");

		} catch (Exception ex){
			Console.WriteLine(ex.Message);
		}
	}
}
}

Bastante simples como podem ver.

A geração do xls fica a cargo da bliblioteca CarlosAG.

Por exemplo, se desejarem ver a especificação dos atributos que são retornados para a BIOS, procurem na microsoft, na secção WMI.

Link para o WMI (BIOS) http://msdn2.microsoft.com/en-us/library/aa394077.aspx.

Para a próxima prometo escrever algo sobre linux/unix.

A API que desenvolvi encontra-se (no sítio do costume :) ) em http://bragatel.pt/coredump/WMI.zip

Cumps

/Ing

1

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Excelente post inginheiro. Acho que vou brincar um pouco com isto... :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

                                                               WMI.Kernel w = new WMI.Kernel();		
		try
		{
			w.Connect();

			w.OpenXLSBook("WMI");
			System.Collections.Hashtable [] na = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.SystemInformation.Win32_Product));

			w.exportHeaderToXLS("Software Instalado",na);
			foreach (System.Collections.Hashtable a in na)
				w.exportDataToXLS(a);

			na = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.Hardware.Win32_MotherboardDevice));

			w.exportHeaderToXLS("Motherboard",na);
			foreach (System.Collections.Hashtable a in na)
				w.exportDataToXLS(a);


			na = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.Hardware.Win32_Printer));

			w.exportHeaderToXLS("Impressoras",na);
			foreach (System.Collections.Hashtable a in na)
				w.exportDataToXLS(a);			

			w.CloseXLSBook("audit.xls");
		} 
		catch (Exception ex)
		{
			Console.WriteLine(ex.Message);
		}

aqui fica um exemplo em que gero um ficheiro audit.xls com os dados da minha Motherboard, Impressoras e do software que tenho instalado no meu PC.

pode fazer download do ficheiro audi.xls que coloquei online em http://bragatel.pt/coredump/audit.xls

/cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Amigo , não existe maneira de saber qual é o nº de série de 1 cd ou dvd que ficará gravado nesses mesmo cd e dvd antes de proceder á respectiva gravação ?

até +

cump.

programadorvb6

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Amigo , não existe maneira de saber qual é o nº de série de 1 cd ou dvd que ficará gravado nesses mesmo cd e dvd antes de proceder á respectiva gravação ?

até +

cump.

programadorvb6

Só depois de proceder à gravação.

WMI.Kernel w = new WMI.Kernel();		
w.Connect();
System.Collections.Hashtable [] na = w.ExecuteWmiQuery(string.Format("Select * from {0}",WMI.Classes.Hardware.Win32_CDROMDrive));
foreach (Hashtable h in na)
  if (h["MediaLoaded"].ToString().ToUpper()=="TRUE")
  Console.WriteLine(h["VolumeSerialNumber"]);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

isso poderia ser bom, no caso de por ex 1 leitor de DVD's ou CD's no PC, ele armazenava o serial number e podia fazer resume de onde tava quando foi parada a execução.... (pk é k eu postei isto aki??:S)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora