DevPinoy.org
A Filipino Developers Community
            

How To: Read your machines information using WMI

I created a demo today about WMI to demostrate to a friend how to read his machine's information. The resulting application is listed below. It's funny because i was just supposed to show him how WMI works but ended up discussing IEnumerators, Hashtables, Enums, Strategy and Command Pattern plus a hint of Generics. Which might make this sample application a little bit too much out of it's title.

Getting to know WMI: so basically, what is WMI? from MSDN Libray.. WMI is described as :

About WMI

Windows Management Instrumentation (WMI) is a component of the Windows operating system that provides management information and control in an enterprise environment. Administrators can use WMI to query and set information on desktop systems, applications, networks, and other enterprise components. Developers can use WMI to create event monitoring applications that alert users when important incidents occur.

Managing Computer Systems with WMI

The purpose of WMI is to provide a standardized means for managing your computer system, be it a local computer or all the computers in an enterprise. In its simplest terms, management is little more than the collecting data about the state of a managed object on the computer system and altering the state of the managed object by changing the data stored about the object. A managed object can be a hardware entity, such as a memory array, a port, or a disk drive. It can also be a software entity, such as a service, a user account, or a page file.

WMI can manage the many components of a computer system. In managing a hard disk, you can use WMI to monitor the amount of free space that remains on the disk. You can also use WMI to remotely alter the state of the drive by deleting files, changing file security, or partitioning or formatting the drive. Using WMI, you can create a management application that monitors an enterprise, provides event-based alerts, and allows a user to control different aspects of an enterprise.

Understanding the Components of WMI

WMI offers a variety of programming interfaces such as Microsoft Visual Basic© Scripting Edition (VBScript), C++, open database connectivity (ODBC), Visual Basic, or HTML that developers can use to customize management applications. System administrators can use WMI by using scripts to automate administration tasks. WMI can integrate with Windows components, such as the Active Directory directory service, to allow for a unified management experience.

.NET makes it easy for developers to access this useful function by just adding a reference to the System.Managment class to their project and utilizing its classes(which is like hundreds) inside your code (correct me if i'm wrong. but i think C++ requires you to create dozen of corks before you could read this resources).

Setting up my project: Basically the first thing that i did was create a base class that would contain the functions that would read WMI classes in my machine. The code below served as the core of my demo.

using System;
using System.Collections.Specialized;
using System.Management;
using System.Collections;

namespace KeithRull.IWannaWMI
{
   public abstract class WindowsInformation
   {
      private string _wmiClass;

      private Hashtable[] _propertyTables;

      public string WMIClass
      {
         get { return _wmiClass; }
         set { _wmiClass = value; }
      }

      public Hashtable[] PropertyTables
      {
         get { return GetPropertyTables(); }
      }

      private Hashtable[] GetPropertyTables()
      {
         //intance number
         int instance = -1;

         //create a new StringCollection
         StringCollection propertyNamesCollection = new StringCollection();
         //create a new ManagementClass using the WMI class name specified in the WMIClass variable
         ManagementClass managementClass = new ManagementClass(WMIClass); 
         //create a new ManagementObjectCollection using the ManagementClass instances
         ManagementObjectCollection managementObjects = managementClass.GetInstances();

         //set the size of our property table to the count of the ManagementObjects
         _propertyTables = new Hashtable[managementObjects.Count];

         //iterate thru each Management object in the ManagementObjectCollection
         foreach (ManagementObject managementObject in managementObjects)
         {
            //create a new hashtable to hold our data
            Hashtable propertyTable = new Hashtable();
            //iteralte thru each PropertyData in the ManagementClass.Properties
            foreach (PropertyData propertyData in managementClass.Properties)
            {
               //add the values to our hashtable
               propertyTable.Add(propertyData.Name, managementObject[propertyData.Name]);
            }
            //add the hashtable to our hastable[]
            _propertyTables[++instance] = propertyTable;
         }

         //return our Hashtable
         return _propertyTables;
      }
      /// <summary>
      /// a method that prints the values contained in our hashtable
      /// </summary>
      public void PrintTables()
      {
         // iterate thru each hashtable in our PropertyTables array
         foreach (Hashtable hashtable in PropertyTables)
         {
            //get the value of each dictionary entry
            foreach (DictionaryEntry dictionaryEntry in hashtable)
            {
               //print the values
               Console.WriteLine("{0}: {1}", dictionaryEntry.Key, dictionaryEntry.Value);
            }
         }
      }
   }
}

I then decided to show 3 different WMI classes which is Win32_LocaldDisk, Win32_Processes and Win32_Services. Here's a look on how setuped the LocalDisk Class:

using System;
using KeithRull.IWannaWMI.Win32Classes.Enums;

namespace KeithRull.IWannaWMI.Win32Classes
{
   //inherit form our base class
   class LogicalDisk: WindowsInformation
   {
      //we then specify the class to read on the constructor level
      public LogicalDisk()
      {
         //this is where we set the class to read by just specifying the enum
         this.WMIClass = Enum.GetName(typeof(OperatingSystemClasses), OperatingSystemClasses.Win32_LogicalDisk);
      }
   }
}

The next thing that i did was to show him .NET generics(nowadays, a .NET demo is not considered a real .NET demo without showing Generics :P) to load 3 WMI classes that i built.

using System.Collections.Generic;
using KeithRull.IWannaWMI.Win32Classes;

namespace KeithRull.IWannaWMI
{
   class WindowsInformationList
   {
      //a generic collection of WindowsInformation class
      private List<WindowsInformation> _informationList = new List<WindowsInformation>();

      //a generic collection of WindowsInformation class
      public List<WindowsInformation> InformationList
      {
         //return our list
         get { return _informationList; }
      }

      public WindowsInformationList()
      {
         //add the WMI classes that to our list 
         _informationList.Add(new Services());
         _informationList.Add(new Processes());
         _informationList.Add(new LogicalDisk());
         // .. add as many as you want
      }
   }
}

and finally, create the Main() method that would run our program:

using System;

namespace KeithRull.IWannaWMI
{
   class Program
   {
      static void Main(string[] args)
      {
         //create a new WindowsInformationList
         WindowsInformationList windowsInfoList = new WindowsInformationList();
         //iterate thru each of the WMI Classes contained in our list
         foreach (WindowsInformation information in windowsInfoList.InformationList)
         {
            information.PrintTables();
         }
      }
   }
}

Here's the resulting screenshot of the running application

   

I hope i didnt went too much out of scope... :P

download the source code here: KeithRull.IWannaWMI.zip (41.2 KB)


Posted Sep 22 2006, 06:57 PM by keithrull
Filed under: , ,

Comments

dehran ph wrote re: How To: Read your machines information using WMI
on 09-22-2006 7:25 PM

We recently researched on using WMI and WQL to create an integrated inventory system as part of our solutions but it seems it is not that reliable. Hardware identities sometimes misrepresented, name of memory etc. I beleieve untill there's stantandard unique naming on these this inventory system will be possible.

cvega wrote re: How To: Read your machines information using WMI
on 09-25-2006 7:07 PM

@dehran,

If you want reliable "hardware" information, then you can code a "kernel mode" filter driver (in C, using WDF), and bring those information back to "user level" (C#) for display and maintenance.

keithrull wrote re: How To: Read your machines information using WMI
on 09-26-2006 1:34 PM

hmmm... thats an interesting approach chris. can you give as sample :D i'd love to see this apporach in action. thanks!

cvega wrote re: How To: Read your machines information using WMI
on 09-26-2006 8:45 PM

I've posted a sample here:

http://community.devpinoy.org/forums/5311/ShowThread.aspx#5311

It's for getting information from BIOS to "learn" installed Floppy Drive in your machine. It uses WinIO from http://www.internals.com

Cheers,

-chris

enrique.prados@a-e.es wrote re: How To: Read your machines information using WMI
on 04-02-2008 5:23 AM

Hi,

how I get list of computers (connected, user connected in those machines) of my company network using WMI ?

Thanks for your attention, greetings.

Please send me an email for answer.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:

Copyright DevPinoy 2005-2008
Powered by Community Server (Commercial Edition), by Telligent Systems