My favorites | English | Sign in

Google Desktop APIs (Labs)

Desktop Gadgets: Retrieve System Information Using Windows Management Instrumentation

This article was written and submitted by an external developer. The Google Desktop Team thanks Benjamin Schirmer for his time and expertise.


Benjamin Schirmer, Gadget Developer
August 2007

Introduction

Although system information is available through the framework.system object, you sometimes need more than it can offer. Another way is to use a hybrid dll, but this is usually a lot of work. This article will show you how to write custom JavaScript objects that retrieve system information using the Windows Management Information (WMI) classes.

The custom object in this article will request operating system information, which can be used to determine the operating system installed on the user's machine. This is very useful if your gadget can only run under a certain operating system, or you can use it to select between OS specific hybrid DLLs you have written.

In the end, we want to be able to use a simple object that gathers operating system information. For example, it should be able to easily detect Windows Vista:

var os = new OS();
if (os.isVista()) {
  doSomething();
}

How To Call A WMI Class

The first thing you need to know is how to call a specific WMI class in JavaScript. Every call to WMI starts with winmgmts:. We will use an impersonationLevel of Impersonate, which will allow us to request all information the current user has access to. After the optional impersonationLevel, what follows is the identification of the computer we want to request information about. To use the current computer, you just use \\.. For other computers, you can use \\hostname. At the end we will add the namespace of our call, which is the standard \root\cimv2 namespace. Your final call should look like this:

winmgmts:{impersonationLevel=Impersonate}\\.\root\cimv2

To use this WMI string to access the information, you must acquire the WMI object using the JavaScript GetObject function. The returned object will provide an ExecQuery method, which allows you to execute queries to the Windows Management Information Interface.

var wmi = GetObject("winmgmts:{impersonationLevel=Impersonate}\\\\.\\root\\cimv2");
var query = "Select * From Win32_OperatingSystem";
e = new Enumerator(wmi.ExecQuery(query));
var data = e.item();

The code above will request a WMI object and all information from the Win32_OperatingSystem class. You can use Enumerator to iterate through all the different results. In our example, we just need the first result. This class has all the information we need to identify the operating system of the user. For additional information, please check out http://msdn2.microsoft.com/en-us/library/aa392727.aspx, which provides a complete list of all WMI classes.

Here are some more WMI classes that can be used for performance monitoring. Please note that some classes require a parameter as input.

Win32_PerfRawData_PerfOS_Memory
Use this class to display the current memory usage.
Win32_PerfRawData_PerfDisk_LogicalDisk
Display the free disk space of partition. This call expects the drive letter as a parameter.
Example: Select * from Win32_PerfRawData_PerfDisk_LogicalDisk Where Name = 'C:'
Win32_PerfRawData_PerfOS_Processor
You can use this class to show the load of the users processor. A call to
Example:Select * From Win32_PerfRawData_PerfOS_Processor Where Name = '0' will retrieve the processor information for the first processor. You can retrieve the number of processors using Win32_ComputerSystem.
It is also possible to change system settings using WMI. You can use it to modify the registry or create files and folders.

Building An Object For The Information

We could use the data variable above to access the different attributes, but it is not very practical since we would have to repeat the query call to WMI whenever we wanted some particular attribute. The easiest way is to create a custom object that provides access to the diffferent attributes, and even additional methods for working with the data.

To create the new object, we first have to create a constructor. This is basically a function that is executed when our object is created with the new call. The constructor executes the code to retrieve the desired information and fills the attributes of the object.

function OS() { 
  var wmi = GetObject("winmgmts:{impersonationLevel=Impersonate}\\\\.\\root\\cimv2");
  var query = "Select * From Win32_OperatingSystem";
  e = new Enumerator(wmi.ExecQuery(query));
  var data = e.item();

  this.windowsSKU = data.OpertingSystemSKU;
  this.serial = data.SerialNumber;
  this.build = data.BuildNumber;
  this.buildType = data.BuildType;
  this.servicePackMajor = data.ServicePackMajorVersion;
  this.servicePackMinor = data.ServicePackMinorVersion;
  this.version = data.Version;
  this.caption = data.Caption;
  this.name = data.Name;
  this.name = this.name.substring(0, this.name.indexOf("|")-1)
}

Our new object OS now provides several attributes, like version and name of the operating system; but we're not finished just yet. We will add some methods to the object to provide additional functionality. In the beginning of this article, I mentioned the isVista method which should tell us if we are running on a Vista machine. This method will use a custom compareVersion method to compare the version of the current operating system to the Vista version string.

OS.prototype.compareVersion = function(version2) {
  var v1 = this.version.split(".");
  var v2 = version2.split(".");
  var result = 0;
  for (var i=0; i<v1.length; i++) {
    if (v1[i] > v2[i]) {
      result = 1;
    }
    else if (v1[i] < v2[i]) {
      result = -1;
    }
    if (result != 0) {
      break;
    }
  }
  if (v2.length > v1.length && v2[v2.length-1] != 0) {
    result = -1;
  }
  return (result == 0);
}

OS.prototype.isVista = function() {
  return this.compareVersion("6.0");
}

If you want, you can extend the object with more of these methods. If you want an isXP method to check for Windows XP, you could simply add:

OS.prototype.isXP = function() {
  return this.compareVersion("5.1");
}

Using The Custom Object

Our custom object is now finished. The best way to make it reusable is to save the code for this object into a separate JavaScript file, for example oshelper.js. If you need the object in a new gadget, simply copy the file to the new project and add it to your xml file. Now that's code reusability!

To use the object in your code, you must create a new OS object and then call the method or attributes you need.

var os = new OS();
if (os.isVista()) {
  alert("You are running:\n"+os.name);
  doSomething();
}

Conclusion

Custom objects are a great way to create reusable code, and WMI is a very powerful way to retrieve system information. Together they make a perfect team. So the next time when you need some information that is not available in the framework, you might want to check if a WMI will provide the information you need.

Be sure to try out the Operating System Gadget to see a gadget that uses the custom object from this article.

Author Bio

Benjamin Schirmer

Benjamin Schirmer holds a diploma in engineering from Albstadt-Sigmaringen University and is an enthusiastic gadget programmer. He loves to explore new technologies. In his spare time, he likes watching movies, TV series, and going out with his friends. In the future, he wants to be a Googler himself. You can visit his gadgets page for a list of all his cool Google Desktop gadgets.



Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.