Home Page Home Page Articoli Alla scoperta di WMI, questo sconosciuto

Alla scoperta di WMI, questo sconosciuto

WMI o Windows Management Instrumentation è un componente fondamentale del sistema operativo Windows. La sua utilità è permettere l'accesso a informazioni fondamentali del sistema, come informazioni sull'hardware, software, servizi, ecc. Vediamo come sfruttarlo con .NET.
Autore: Giovanni Ferron Livello:
WMI (Windows Management Instrumentation) è un insieme di interfacce che permettono di interagire con le informazioni di sistema, e modificarle. Le WMI si possono utilizzare in applicazioni di controllo e gestione dei sistemi, come ad esempio il controllo delle risore di un server, in questo esempio vedremo come interagire con le schede di rete per cambiare gli indirizzi IP.
Dal punto di vista .NET con WMI non c'è bisogno di alcuna installazione visto che tutto è compreso nel sistema operativo inoltre a livello di classi bisogna dire che è già tutto compreso nell'apposito namespace System.Management, ma Microsoft comunque ci offre dei tool per lo sviluppo che ci possono aiutare, primo fra tutti i WMI Tools che possono essere scaricati qui: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=6430F853-1120-48DB-8CC5-F2ABDC3ED314 ">Download WMI Tools

Questo Tool ci permette di navigare tra le informazioni di sistema come l'esplora risorse, inoltre mostra per ogni oggetto le dipendenze con altri oggetti. Inoltre è possibile installare un modulo per Visual Studio .NET che permette la navigazione e l?utilizzo degli oggetti direttamente da visual studio, ecco uno screenshot del modulo nel Server Explorer. Questo lo poete scaricare qui:
http://www.microsoft.com/downloads/details.aspx?FamilyID=62d91a63-1253-4ea6-8599-68fb3ef77de1&displaylang=it ">Estensioni WMI per Esplora server di Visual Studio .NET 2003

Le estensioni per VS.NET2003 in funzione
Le estensioni per VS.NET2003 in funzione


Architettura di WMI
La tecnologia WMI è costituita da due componenti principali:
? Struttura di gestione: La struttura di gestione include il CIM (Common Information Model) Object Manager, che permette l?accesso univoco alle informazioni di sistema contenute nel CIM Repository
? Provider di accesso: Funzionano come intermediari tra il CIM e gli oggetti controllati, attraverso le API possono gestire il flusso di informazioni dal WMI fino agli oggetti di sistema. Inoltre gestiscono gli eventi e associano le informazioni alle classi di oggetti presenti nel CIM.

Ecco la tabella con l?elenco dei provider:


Tutte le informazioni salvate nel WMI sono descritte utilizzando il CIM (Common Information Model), che è stato studiato dalla Distributed Management Task Force (http://www.dmtf.org ">http://www.dmtf.org ), ed è uno standard unificato che per fornire un framework comune definisce tutto in base a set di classi, proprietà e associazioni.
Il CIM fornisce:
? La possibilità di gestire gli oggetti come classi astratte, per poter interagire con una periferica o con un processo.
? Proprietà e Metodi per gestire le classi, ad esempio la classe Hard Disk avrà la proprietà "Spazio disponibile", e un metodo per formattare il disco.
? Namespace per gestire le classi di oggetti.

Tutto questo ci permette di utilizzare facilmente ogni nostra periferica come se stessimo utilizzando oggetti di un qualsiasi linguaggio ad oggetti.

Dalla teoria alla pratica. Al lavoro!
Bene dopo questa veloce introduzione sull?architettura, passiamo alla pratica, e come esempio pratico abbiamo scelto un?applicazione che ci permette di visualizzare l?elenco delle nostre interfacce di rete, per ognuna di queste visualizzare gli indirizzi IP e poterli modificare a nostro piacimento.
Iniziamo con il ricavare l?elenco delle nostre interfacce di rete, per fare questo, dovremo interagire con il provider Win32 ed utilizzare il namespace root\cimv2 (vedi tabella namespace), e creare un oggetto ManagementObjectSearcher, e come parametro in ingresso chiede una query al database, in questo caso gli passiamo un oggetto SelectQuery che rappresenta una query su una classe specifica, in questo caso la classe Win32_NetworkAdapter che identifica le interfacce di rete.


//creo l'oggetto query
SelectQuery oq = new SelectQuery("Win32_NetworkAdapter");
//Creo il searcher per elencare le interfaccie
ManagementObjectSearcher searcher = new ManagementObjectSearcher(oq);


L?ggetto searcher ci mette a disposizione il metodo get() che crea una collection di oggetti, quindi noi cicliamo per ricavare un oggetto ManagementObject, che rappresenta la nostra interfaccia con la periferica. Nel ciclo ricaviamo il codice univoco della periferica, che ci servirà per interrogare la classe Win32_NetworkAdapterConfiguration che permette di recuperare i dati di configurazione della singola scheda, e una volta recuperato il nostro oggetto lo inseriremo in una collection:


//ciclo sulla collection del searcher
foreach(ManagementObject obj in searcher.Get())
{
//ricavo l'id della periferica e interrogo la Win32_NetworkAdapterConfiguration
objectManagement objManage = new objectManagement((string)obj["DeviceID"]);
//aggiungo l'oggetto alla collection
adapterCollection.Add(new adapter(objManage.objWMI));
}


In queste righe di codice abbiamo utilizzato ben tre oggetti personalizzati, un oggetto ObjectManagement che ci restituisce tramite query l?oggetto che punta alle caratteristiche della scheda, ecco il costruttore:


public objectManagement(string strDeviceID)
{
string strPath;
strPath = ("ROOT\\CIMV2:Win32_NetworkAdapterConfiguration" + (".Index=" + strDeviceID));
myObj = new ManagementObject(strPath);
}


Ricavato l?oggetto lo passiamo alla classe Adapter che ricaverà le informazioni di cui abbiamo bisogno, ad esempio l'IP e la descrizione della nostra scheda:


//costruttore classe adapter
public adapter(ManagementBaseObject objWMI)
{
//ricavo l?IP
if(objWMI["IPAddress"] != null){
IPAddress = (string[])objWMI.Properties["IPAddress"].Value;
}
//ricavo la descrizione
if(objWMI["Description"] != null){
Description = objWMI["Description"].ToString();
}
//Salviamo anche l?ID della periferica
if(objWMI["Index"] != null){
DeviceID = Convert.ToUInt32(objWMI["Index"]);
}
}


Oltre al MACAddress possiamo memorizzare tutte le proprietà della nostra scheda, un elenco completo potete vederlo utilizzando il WMI Object Browser che avete installato con i WMI Tools. Ricavati tutti i dati inseriamo il nostro oggetto nella nostra collection personalizzata, che eredita dalla classe CollectionBase, questo ci permette un accesso molto più comodo e veloce rispetto agli array, ecco il codice della collection:


// classe collection oggetti adapter
public class adaptersCollection : CollectionBase
{
//metodo aggiunta oggetto adapter
public void Add(adapter adapterItem)
{
List.Add(adapterItem);
}
}


Ora che abbiamo creato la nostra collection, non dobbiamo far altro che creare un groupBox che elenchi i nostri oggetti:


// Ciclo su tutti gli oggetti adapter contenuti nella mia collection
foreach(wmiClassesSharp.adapter obj in objAdapt.adapterCollection)
{
// Aggiungo la scheda
dropAdapters.Items.Add(obj.Description);
}


ed ecco il nostro primo risultato:



Ora che abbiamo l?elenco delle nostre schede vogliamo visualizzare l?IP di una singola interfaccia, quindi creiamo una funzione che intercetta il cambiamento di indice del nostro dropBox, recupera l?oggetto dalla collection e visualizza in una serie di quattro textbox l?IP:


// fuzione che intercetta il cambiamento di indice
private void dropAdapters_SelectedIndexChanged(object sender, System.EventArgs e)
{
// cerco l?oggetto nella collection
wmiClassesSharp.adapter myAdapt = objAdapt.adapterCollection.findByDeviceID(Convert.ToString(dropAdapters.SelectedIndex + 1));
// imposto l?ip nei textbox, facendo uno split per dividere l?ip
if(myAdapt.IPAddress != null){
string[] myIp = myAdapt.IPAddress[0].Split(".".ToCharArray());
txtIP0.Text = myIp[0];
txtIP1.Text = myIp[1];
txtIP2.Text = myIp[2];
txtIP3.Text = myIp[3];
}
}


come vedete per ricavare l?oggetto dalla collection viene utilizzato un metodo personalizzato findByDeviceID, che non fa altro che ciclare e restituire l?oggetto con l?ID specificato.


// metodo che restituisce un oggetto dalla collection
public adapter findByDeviceID(string strDeviceID)
{
adapter myAdapt = null;
// ciclo sulla collection
foreach(adapter objAdapt in List)
{
// controllo che l?oggetto abbia l?id cercato
if(objAdapt.DeviceID == strDeviceID)
{
// imposto l?oggetto e esco dal ciclo
myAdapt = objAdapt;
break;
}
}
// ritorno il mio oggetto
return myAdapt;
}


ed ecco il risultato:




Modifica dei valori
Dopo esser riusciti a ricavare le proprietà della nostra scheda vediamo come andare a modificarne I valori. Per poter modificare un valore nelle WMI dobbiamo invocare uno dei metodi supportati dalla classe tramite il metodo InvokeMethod, questo metodo richiede come parametri il nome del metodo, l?array con i parametri e una serie di opzioni, e ci restituirà un array con i parametri in uscita. Quindi creo una funzione che accetta come parametri in ingrasso l?oggetto management che punta alla scheda, il nuovo indirizzo, la subnet e il gateway e prima di invocare il metodo creiamo l?array dei parametri in ingresso e in uscita.


public void setIP(adapter myObj, string address, string subnet, string gateway)
{

ManagementBaseObject myParamsIn;
ManagementBaseObject myParamsOut;

. . .
}


Dopo di che inizializziamo l?array con i parametri necessari, utilizzando il metodo GetMethodParameters che non fa altro che interrogare il metodo.


// Interrogo il metodo
myParamsIn = myObj.GetMethodParameters("EnableStatic");
// Imposto i parametri necessari
myParamsIn["IPAddress"] = new string[] {address};
myParamsIn["SubnetMask"] = new string[] {subnet};

A questo punto invoco il metodo EnableStatic che mi imposta i valori della scheda di rete

// Modifico gli indirizzi
myParamsOut = myObj.InvokeMethod("EnableStatic", myParamsIn, null);

Lo stesso metodo lo usiamo per impostare il gateway della nostra scheda

// Interrogo il metodo
myParamsIn = myObj.GetMethodParameters("SetGateways");
// Imposto i parametri necessari
myParamsIn["DefaultIPGateway"] = new string[] {gateway};
myParamsIn["GatewayCostMetric"] = new int[] {1};
// Modifico gli indirizzi
myParamsOut = myObj.InvokeMethod("SetGateways", myParamsIn, null);


Se invece vogliamo impostare la nostra scheda in modalità DHCP, non dobbiamo far altro che richiamare il metodo EnableDHCP


myParamsIn = myObj.GetMethodParameters("EnableDHCP");
myParamsOut = myObj.InvokeMethod("EnableDHCP", myParamsIn, null);


Conclusioni
Nel seguente articolo abbiamo esplorato l?architettura WMI e capito come interagire con quest?ultima, implementando un semplice programma per cambiare gli IP della nostra scheda di rete, ma potremmo anche sviluppare applicazioni per il controllo di qualsiasi periferica, oppure applicazioni web per il controllo dei nostri server. Inoltre I più curiosi possono esplorare soluzioni altrernative, infatti sono disponibili vari metodi di accesso al repository WMI, tra cui anche ODBC per facilitare il lavoro a noi poveri sviluppatori, quindi buon lavoro!
Voto medio articolo: 4.3 Numero Voti: 4

File allegati


125_ipHellVB.zip (65 Kbyte)
125_ipHellCS.zip (65 Kbyte)
Giovanni Ferron

Giovanni Ferron

Sviluppatore dal 2000. Collabora a grandi progetti nella creazione di portali e intranet aziendali. Attualmente ha lasciato la terra natia per una nuova avventura in Australia, dove lavora come programmatore web per una emittente radio Australiana. Profilo completo

Articoli collegati

Importare dati di Excel con .NET tramite ODBC o OLEDB e Drag & Drop
Spesso in ambito aziendale è necessario adattare le proprie applicazioni e consentire che possano leggere e operare su file e dati provenienti dai tools della suite di Office fra cui uno dei più usati è Excel. Vediamo quindi come importare dati da file XLS tramite ODBC/OLEDB e Drag & Drop.
Autore: Marco Farina | Difficoltà:
Gestire le Access Control List (ACL) NTFS di file e directory con .NET
Scopriamo come nel .NET Framework 2.0 sia diventato facile recuperare e modificare la lista controllo accessi dei file e directory e in generale come gestire le ACL.
Autore: Marco Caruso | Difficoltà: | Commenti: 1 | Voto:
Costruire un client FTP usando il .NET Framework 2.0
In questo articolo tratteremo una delle novità più attese del .NET Framework 2.0, le classi per l'utilizzo del protocollo FTP. Realizzeremo un mini client FTP con alcune fra le funzionalità più comuni.
Autore: Giovanni Ferron | Difficoltà: | Commenti: 28
Gestire e sfruttare i campi BLOB usando .NET
I database server sono software con una potenza elevata e offrono una vasta gamma di features che spesso non vengono utilizzate. Una di queste sono i campi BLOB (campi per contenere dati in formato binario). Vediamo in questo articolo come utilizzarli con .NET.
Autore: David De Giacomi | Difficoltà: | Commenti: 13
Catturare immagini da una Webcam con .NET
In questo articolo mostreremo come è possibile costruire una applicazione per catturare immagini da una Webcam, utilizzando componenti già presenti in Windows, in questo caso l' Avicap32.dll
Autore: Giovanni Ferron | Difficoltà: | Commenti: 22 | Voto:
Usare il protocollo POP3 per creare un Client di posta
Volete costruirvi un client di posta? Volete costruire una Web Mail ? Ecco un articolo che vi introduce al protocollo POP3 e vi insegna come costruire un mini client di posta elettronica.
Autore: Giovanni Ferron | Difficoltà: | Commenti: 2 | Voto:
La stampa di una Win Form
Vedremo in questo articolo i passi necessari per creare una stampa sia di testo che di grafica di una WinForm attraverso .NET.
Autore: Marco Caruso | Difficoltà: | Commenti: 9 | Voto:
Creare un Setup di un progetto con Visual Studio .NET
Ecco delle semplici ma dettagliate istruzioni passo-passo per costruire un pacchetto di Setup (Setup Package) per le nostre Applicazioni WinForms.
Autore: Marco Caruso | Difficoltà: | Commenti: 18
Creare un?icona nella Taskbar di Windows con .NET
Scoprirete come potenziare la vostra applicazione aggiungendo un'icona nella barra di Windows nella famosa Tray Area a fianco dell'orologio del sistema. Disponibile sia codice VB.NET che C#.
Autore: Giovanni Ferron | Difficoltà: | Commenti: 1 | Voto:
Costruire un Servizio di Windows usando .NET
Un avanzato tutorial che vi spiegherà passo passo e in modo dettagliato le istruzioni per costruire un Servizio Windows, utilizzando ciò che il .NET Framework ci mette a disposizione. Disponibile sia codice C# che VB.NET.
Autore: Giovanni Ferron | Difficoltà: | Commenti: 13 | Voto:
Windows XP Visual Styles con .NET e Win Forms
Come usare lo stile XP nelle vostre applicazioni .NET ? Questo articolo vi spiega come applicare a Buttons, Textbox, ListViews (ai controlli di Windows in genere) lo stile/tema grafico della GUI introdotto dal sistema operativo Windows XP.
Autore: David De Giacomi | Difficoltà: | Commenti: 7
Come sfruttare le funzioni di una DLL unmanaged esterna creata in C/C++
Come usare la classe DllImportAttribute messa a disposizione dal namespace System.Runtime.InteropServices per sfruttare le funzioni di una DLL unmanaged Win32 old-style scritta con Visual C++ 6.0
Autore: David De Giacomi | Difficoltà: | Commenti: 4 | Voto:
Creare una DLL in Visual C++ 6.0
Vedremo in questo articolo come creare una Dynamic Link Link Library, comunemente chiamata DLL con Visual C++ 6.0. Questo passo è necessario per poi dimostrare l'utilizzo di librerie C/C++ in .NET tramite il package System.Runtime.InteropServices
Autore: David De Giacomi | Difficoltà: | Commenti: 11 | Voto:
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5