La WMI et C# partie 1

Christian TORREZE

Cet article a pour but de présenter ce qu'est la WMI et comment l'utiliser en C#.

N'hésitez pas à commenter cet article ! Commentez ♪

- Titre : La WMI et C# partie 1

- Auteur : Christian TORREZE

- Parution : 5 juin 2003

- Licence : Copyright ® 2003 Christian TORREZE. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- Présentation et historique

- I. À quoi ça sert ?

- II. Comment ça marche ?

- III. Les langages supportant WMI

- IV. Interrogation WMI en C#

- IV-A. La connexion au service WMI

- IV-B. L'extraction des ressources

- IV-C. La gestion des propriétés des ressources

- V. Conclusion

Présentation et historique

WMI (Windows Management Instrumentation) est issu d'une initiative de normalisation d'un groupe appelé DMTF (Distributed Management Task Force) auquel Microsoft appartient.

L'objectif étant que tous les systèmes soient gérables via une même interface normalisée.
De ce groupe est née la norme CIM (Common Information Model). CIM est un schéma orienté objet pour la gestion des systèmes, des réseaux, des applications, des bases de données et des périphériques.

C'est Windows qui a le plus mis en ouvre WMI dans son système d'exploitation. Il est apparu pour la première fois en 1998 dans le service Pack 4 de Windows NT 4.0.Depuis il est présent dans Windows 2000, ME, XP et .NET Server. Pour les versions 95/98/NT on peut télécharger le Kit WMI sur le site de Microsoft.

I - À quoi ça sert ?

WMI permet d'accéder aux ressources d'un ordinateur sous Windows, les configurer, les gérer et les interroger.

Ce qui sous-entend la possibilité de gérer une machine, y faire exécuter un programme, arrêter un service, la rebooter ou l'arrêter, voir les ressources system, vous abonner à un événement et recevoir une alerte, interroger le service WMI d'une application (vous pouvez aussi écrire une application offrant un serveur WMI), etc.

Avec WMI vous accédez à tout ceci sans passer par les API, ainsi les développeurs n'ont pas besoin de connaître plusieurs API pour créer des applications puissantes ou interroger les composants de la machine hôte de leur application.

Combien de fois avez-vous vu sur les news group la question : «  Comment connaître le numéro de série d'un disque dur » ?

De plus l'accès ne se limite pas à la machine où s'exécute le logiciel ou le script.
On peut aussi interroger un ordinateur situé sur le réseau ou tous les ordinateurs d'un même groupe de travail.

Pratique pour un administrateur réseau pour suivre son parc machine, le surveiller, recevoir des alertes, diagnostiquer, rebooter une machine distante ou même la stopper, etc.

Citons en passant que WMI est l'une des technologies employées dans MOM (Microsoft Operations Manager).

II - Comment ça marche ?

La ressource gérée est interrogeable / utilisable par WMI via une API.

L'infrastructure WMI possède :

- des fournisseurs qui représentent chacun un objet géré. Le fournisseur de la ressource communique avec elle à l'aide de son API et expose un modèle d'accès normalisé ;

- le CIMOM (Common Information Model Object Manager) appelé «  Service WMI » dans le monde de Windows.C'est le moteur de ce système. Par lui transitent les demandes des logiciels accédant à WMI. Il enregistre les fournisseurs, les stocke dans le CIM, gère la sécurité en validant la demande de l'utilisateur avant la connexion à WMI, etc. ;

- le CIM (Common Information Model) appelé aussi «  référentiel WMI ».Il représente de manière uniforme les informations de configuration. Inspiré du concept de classes il stocke les représentations des ressources. Il contient surtout le plan général des ressources et quelques données statiques.

III - Les langages supportant WMI

VBScript

Vous pouvez copier/coller le texte suivant dans le bloc note et le sauvegarder avec une extension .vbs puis lancer ce script exemple :

On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_LogicalDisk",,48)
For Each objItem in colItems
Wscript.Echo "Access: " & objItem.Access
Wscript.Echo "Availability: " & objItem.Availability
Wscript.Echo "BlockSize: " & objItem.BlockSize
Wscript.Echo "Caption: " & objItem.Caption
Wscript.Echo "Compressed: " & objItem.Compressed
Wscript.Echo "ConfigManagerErrorCode: " & objItem.ConfigManagerErrorCode
Wscript.Echo "ConfigManagerUserConfig: " & objItem.ConfigManagerUserConfig
Wscript.Echo "CreationClassName: " & objItem.CreationClassName
Wscript.Echo "Description: " & objItem.Description
Wscript.Echo "DeviceID: " & objItem.DeviceID
Wscript.Echo "DriveType: " & objItem.DriveType
Wscript.Echo "ErrorCleared: " & objItem.ErrorCleared
Wscript.Echo "ErrorDescription: " & objItem.ErrorDescription
Wscript.Echo "ErrorMethodology: " & objItem.ErrorMethodology
Wscript.Echo "FileSystem: " & objItem.FileSystem
Wscript.Echo "FreeSpace: " & objItem.FreeSpace
Wscript.Echo "InstallDate: " & objItem.InstallDate
Wscript.Echo "LastErrorCode: " & objItem.LastErrorCode
Wscript.Echo "MaximumComponentLength: " & objItem.MaximumComponentLength
Wscript.Echo "MediaType: " & objItem.MediaType
Wscript.Echo "Name: " & objItem.Name
Wscript.Echo "NumberOfBlocks: " & objItem.NumberOfBlocks
Wscript.Echo "PNPDeviceID: " & objItem.PNPDeviceID
Wscript.Echo "PowerManagementCapabilities: " & objItem.PowerManagementCapabilities
Wscript.Echo "PowerManagementSupported: " & objItem.PowerManagementSupported
Wscript.Echo "ProviderName: " & objItem.ProviderName
Wscript.Echo "Purpose: " & objItem.Purpose
Wscript.Echo "Size: " & objItem.Size
Wscript.Echo "Status: " & objItem.Status
Wscript.Echo "StatusInfo: " & objItem.StatusInfo
Wscript.Echo "SupportsFileBasedCompression: " & objItem.SupportsFileBasedCompression
Wscript.Echo "SystemCreationClassName: " & objItem.SystemCreationClassName
Wscript.Echo "SystemName: " & objItem.SystemName
Wscript.Echo "VolumeName: " & objItem.VolumeName
Wscript.Echo "VolumeSerialNumber: " & objItem.VolumeSerialNumber
Next

Un petit outil intéressant que distribue Microsoft est le Scriptomatic. Il est téléchargeable ici.

Les langages capables d'appeler les fonctions des API Windows.

On peut trouver sur code central un exemple en Delphi http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19655

Et voici un exemple en C++ : http://www.codeguru.com/system/WMI_using.html
Il nécessite d'installer Windows 2000 Driver Development Kits

Le Framework .NET

Le Framework étant multi plateforme WMI est le seul moyen pour accéder au hardware de la machine hôte.

Il offre tous les objets et commandes pour WMI. On peut alors développer, en très peut de lignes une application se «  servant » de WMI.

Ici nous utiliserons le C#, bien que l'on puisse bien entendu prendre VB.NET.

IV - Interrogation WMI en C#

C'est la librairie de class System.Management qui est utilisée.

Il y a trois étapes à effectuer :

1. La connexion au service ;

2. L'extraction des ressources ;

3. La gestion des propriétés des ressources.

IV-A - La connexion au service WMI

//Spécification de tous les paramètres requis pour créer une connexion avec la classe ConnectionOptions.

ConnectionOptions aConnectionOptions = new ConnectionOptions();
ConnectionOptions.Username = "domain\\username";
ConnectionOptions.Password = "password";

//Utilisation du namespace WMI dans lequel les opérations de gestion vont être effectuées.
ManagementScope aManagementScope = new ManagementScope("\\\\IPOrdi\\root\\cimv2", ConnectionOptions);

IPOrdi est l'adresse IP ou le nom de la machine à inspecter.
Si la machine est locale, on peut aussi écrire : «  localhost » ou " . " .

new ManagementScope ("\\\\IPOrdi\\root\\cimv2 "

new ManagementScope (@"\\IPOrdi\root\cimv2 "

Verbatim string literal peut aussi permettre «  une string multiligne » :
Il suffit de passer à la ligne suivante, par un return, dans l'éditeur de code.

Exemple :

string MyString = @"C'est
vraiment
pratique "

IV-B - L'extraction des ressources

//La classe ObjectQuery représente une requête de gestion qui retourne des instances ou des classes
System.Management.ObjectQuery aObjectQuery = new System.Management.ObjectQuery("select * from Win32_LogicalDisk where DriveType=3");

//La classe ManagementObjectSearcher permet d'extraire une collection d'objets de gestion, en fonction de la requête spécifiée lors de son instanciation par le paramètre ObjectQuery ou directement par une string si l'on "code en dur"
ManagementObjectSearcher aManagementObjectSearcher = new managementObjectSearcher(aManagementScope, aObjectQuery);

//ManagementObjectCollection représente différentes collections d'objets de gestion extraits via WMI.
ManagementObjectCollection aManagementObjectCollection = aManagementObjectSearcher.Get();

Voilà pour obtenir les infos voulues en faisant une interrogation SQL, tout simplement. Win32_LogicalDisk est la classe WMI qui permet d'accéder à la description des lecteurs disques présents sur la machine. Dans cet exemple on demande toutes les propriétés des lecteurs locaux non removable.

On peut affiner la requête SQL :

"Select name,VolumeName From Win32_LogicalDisk Where FreeSpace < 10000000000 And DriveType = 3"

Le langage d'interrogation de WMI est appelé WQL, il est très proche de ANSI SQL.

IV-C - La gestion des propriétés des ressources

Ici nous nous limiterons à afficher les informations «  name » et «  VolumeName » dans un richTextBox.

//ManagementObject est un objet de gestion de données.
foreach ( ManagementObject aManagementObject in aManagementObjectCollection)
{
richTextBoxInfos.Text += "Name : " + aManagementObject ["name"].ToString();
richTextBoxInfos.Text += " : " + aManagementObject ["VolumeName"].ToString()+ "\r\n";
}

Ce code affiche dans richTextBoxInfos les noms des disques et les noms de volume de l'ordinateur.

Et si l'on veut afficher toutes les informations d'une propriété ?

Dans certains cas la liste est longue, très longue !

Si l'on veut afficher de manière exhaustive tous les paramètres d'une section, il suffit «  d'énumérer » toutes les informations relatives à la propriété WMI interrogée.

foreach ( ManagementObject aManagementObject in aManagementObjectCollection )
{
//Ajout d'un retour chariot pour séparer à l'affichage les objets extraits.
richTextBoxInfos.Text += "\r\n";
//PropertyData représente les informations retournées par la propriété WMI de l'objet extrait par le ManagementObject utilisé.
foreach (System.Management.PropertyData aPropertyData in aManagementObject.Properties)
{
richTextBoxInfos.Text += aPropertyData.Name + " : " + System.Convert.ToString(aManagementObject[aPropertyData.Name])+ "\r\n";
}
}

V - Conclusion

Nous avons fait connaissance avec WMI qui «  contient » assez de matière pour écrire un livre.
Je pense vous avoir montré la puissance de C# dans ce domaine.

Vous trouverez ici la source d'une application que j'ai développée. Je vous laisse le soin de le copier coller dans votre outil de développement C#.

Dans une deuxième partie, nous verrons comment voir et utiliser les services d'une machine.