jWMI – Query Windows WMI from Java
Java applications need more platform information
One of the key design facets of Java Technology is that java programs execute within a virtual machine. Because all java applications execute within a virtual machine, the applications are abstracted from the operating system. In most cases, this is exactly what the application developer is looking for because the virtual machine provides security, stability for the underlying operating system in addition to environment consistency and reproducibility for the application. Additionally, the developer benefits from the compile-once, run anywhere benefits of the virtual machine.
One of the challenges encountered when implementing java applications is that the applications themselves are typically unable to interact directly with the operating system due to the sand-boxed nature of the programs execution environment, namely the virtual machine. This abstraction can make it difficult to determine specific information about the platform on which the application is being run. While this is one of the architectural advantages of the java environment, it can also get in the way when a legitimate application needs to access information about the host operating system.
WMI – Windows Management Instrumentation
In order to allow applications to access operating system and platform specific information, Microsoft has provided a simple to use, SQL-like API called WMI (Windows Management Instrumentation). WMI is provided as a default configuration within XP-Home and later operating systems. It can even be added to earlier operating systems such as Windows 2000 via a windows update.
WMI queries can be executed from all of the Microsoft supported programming languages including, C/C++, .NET, Visual Basic, COM, C# and the various scripting languages such as ASP, VBScript and BAT (via command line tools).
So what does a WMI query look like? A WMI query is actually fairly simple. If you have ever worked with SQL, then you will pick up the syntax rather quickly. In fact, the WMI query language is actually a modified subset of standard SQL.
Select Name from Win32_ComputerSystem
This example will select the ‘Name’ field from the Win32_ComputerSystem class. This value is actually the name of your computer that you can set in the ‘My Computer-Properties’ dialog.
In addition to simple queries, you can also create WMI queries that filter their results. For example, the following query will only return the system services that are in the Stopped state:
Select * from Win32_Service WHERE State = 'Stopped'
Executing WMI Queries
There are numerous ways to execute a WMI query including a command line application and API’s in the various Microsoft programming languages. Windows XP-Pro and later server OS versions contain the WMIC.exe command line application. This allows a batch script to easily access WMI information. Additionally, VBScript can use API calls to execute a query.
The following example shows how easy it is to obtain WMI data via the WMIC.exe application:
wmic path Win32_ComputerSystem get Name
Obtaining WMI data from VBScript is also quite simple:
Dim oWMI : Set oWMI = GetObject("winmgmts:") Dim classComponent : Set classComponent = oWMI.ExecQuery("Select Name from Win32_ComputerSystem") Dim obj, strData For Each obj in classComponent strData = strData & obj. & VBCrLf Next wscript.echo strData
A cross process WMI interface
In order to access the WMI data from Java, we will need to be able to access the API. Unfortunately, Java does not have this built into the language, nor have I located a suitable class or library which provides this functionality. So, in order to make WMI data available to a java application, I embarked on search for ways to call a Microsoft “solution” to obtain the data for me.
My first attempt was to use WMIC.exe along with the Java Process class to simply execute the process from my java application, grab the output and poof, there would be the WMI data. After a bit of fiddling, I got this approach to work. When testing the solution on various Windows platforms, I soon discovered that not all OS’s have WMIC.exe. Unfortunately, WMIC.exe is not available on Window XP-Home and it is likely not available on the entry level versions of Vista either.
After this discovery, it was time to try another approach. This time I decided to use VBScript to access the information. In this model, I would dynamically create a VBScript file at java program runtime and then execute it from java within a cmd.exe process and obtain the output from the stdout of the process. Fortunately, this second attempt proved to work well and since VBScript is available on all recent versions of Windows, this is the approach that I finally implemented.
Accessing WMI in Java – the jWMI libary
The jWMI class is a fairly simple class which allows an application to execute an arbitrary query against the WMI subsystem. jWMI is easy to use and contains member variable defines for many of the available WMI classes.
Executing a WMI query via jWMI is simple, as can be seen in the following example:
String name = getWMIValue("Select Name from Win32_ComputerSystem", "Name");
You can also query multiple data fields as shown in the following example. when querying multiple data fields from a class, be sure to place the field names in the same order as the query describes them. This will help avoid confusion.
String name = getWMIValue("Select Description, Manufacturer from Win32_PnPEntity", "Description,Manufacturer");
As shown in a previous example, you can also execute more complex queries such as the following. In this case, we provide ‘Name’ as the desired field since we want the name of each service that is in a Stopped state:
String name = getWMIValue("Select * from Win32_Service WHERE State = 'Stopped'", "Name");
jWMI – A WMIC.exe replacement for Windows XP-Home
In addition to providing a programmatic API for accessing WMI data, jWMI provides a command line interface that allows you to use it from within batch scripts. It’s usage is quite simple and behavior is the same as the programmatic API.
java jWMI <wmiQuery> <commaSeparatedListOfDesiredFields>
For example, to run the “Description,Manufacturer” query (above) via the command line, you would enter:
C:\dev\jWmi\bin>java com.citumpe.ctpTools.jWMI "Select Description, Manufacturer from Win32_PnPEntity" "Description,Manufacturer"
This project is available under a modified BSD license.
You MUST provide a link back to this page on your website or in your end-user product documentation which states that your project is using this code. If you do not provide a link back, you are in violation of this licensing agreement and you may not continue to use the jWMI source code. Thank you for being honest and honorable in your use of jWMI.
You may download the source and binary here: jWmi (7180).
Help support jWMI!
If you are using jWMI in your project, please consider donating to support the continued development of jWMI. If you are looking for a book about WMI, you can support this project by ordering your book via one of the Amazon links below. Thank you for supporting jWMI!!!
- Initial release
Here are some good reference manuals that I have found for WMI:
Leave a comment