Archive for the ‘programming’ Category

Collecting Hardware Information using C# and WMI

Thursday, February 18th, 2010

I’ve been playing around with C# lately putting together a little app that would collect hardware information about the computer it was running on. Stuff like CPU speed, amount of installed memory, CPU manufacturer, amount of cache, make and model of the machine and etc. I know that there is stuff out there that does this soft of thing well – for example CPU-Z which is excellent. What I wanted though was something a bit more idiot friendly.

The reasoning behind this is simple: users are idiots. Whenever I do any sort of support calls or troubleshooting with my users I spend most of the time trying to extract information out of them. What kind of computer do they have (standard answer: a laptop), how fast it is, how much memory there is, what is their IP address, subnet and default gateway, what DNS server they are using, the applications they have installed, the services they are currently running and etc… No one ever knows these details of the top of their head, and explaining to them how to check these details is time consuming. I mean, if you never had to explain to someone what a pingoogle is, then you probably haven’t done much network troubleshooting over the phone (for the record, that is what a luser will type if you don’t say SPACE between ping and google.com).

Wouldn’t it be nice if I could just offload all that diagnostic bullshit onto a piece of software that would extract bunch of important system information and display it on the screen so that the user could read it to me, or paste it into email. Or better yet, have the app periodically submit all this information to an online form somewhere so that I would have an ongoing record of the users machine and changes that were made to it. Yes, it would be great. I’d just need to write such a thing – and I could customize it specifically to my needs.

I already know how to send HTTPS POST requests with C# so I just needed to figure out how to extract the hardware information from the bowels of the users machine. After doing some research I found out that all I need is to learn how to talk to WMI.

In case you didn’t know WMI is a little magical gnome that lives inside your computer case, and communicates using (of all things) SQL. You can send that little guy an SQL like query and he will hop over to the CPU, lift the heat sink and read the clock speed off the device for you. Speak to him however you will need to add a System.Management reference to your project:

Add the System.Management reference

Once it is done, you need to familiarize yourself with Mr. ManagementObjectSearcher who is the dude that goes and pokes the gnome with the stick, hands him SQL queries and retrieves the results back for you. You initialize him with an SQL query like so:

ManagementObjectSearcher searcher = 
   new ManagementObjectSearcher("SELECT * FROM Win32_Processor");

No, seriously, that’s how it works. The name of the “tables” and attributes you can use in your queries can be found in the WMI documentation on MSDN. For example, if you want to find out information about the CPU you want to query the Win32_Processor class. If you read the docs you will find out that it has few dozen attributes such as Name which returns a string containing a human readable description of the CPU or MaxClockSpeed which returns maximum clock speed in Hz as an unsigned 32 bit integer.

Once you initialize your searcher object with an appropriate query, you will need to retrieve the results. Let me show you how to do this below:

ManagementObjectSearcher searcher = 
   new ManagementObjectSearcher("SELECT 
                                   maxclockspeed, 
                                   datawidth, 
                                   name, 
                                   manufacturer 
                                FROM 
                                   Win32_Processor");
 
ManagementObjectCollection objCol = searcher.Get();

The Get method of our searcher object rerurns a ManagementObjectCollection instance populated with our results. In theory all the WMI queries can return multiple “data rows” (for example, if you have multiple CPU’s you will get a ManagementObject associated with each of them), and so the answers get bundled into a collection. In practice however we usually just get a single answer so the whole collection thing is a bit unnecessary – and unwieldy to work with. The least verbose method of extracting our data I can think of is to plug it into a foreach loop like this:

foreach (ManagementObject mgtObject in objCol)
{
     Console.Write(mgtObject["maxclockspeed"].ToString()+ Environment.NewLine);
     Console.Write(mgtObject["datawidth"].ToString()+ Environment.NewLine);
     Console.Write(mgtObject["name"].ToString()+ Environment.NewLine);
     Console.Write(mgtObject["manufacturer"].ToString() + Environment.NewLine);              
}

Since 90% of the time we only expect to see a single object inside the collection this is fairly quick, single iteration loop. You can actually test whether or not your collection has more than a single item by inspecting it’s Count attribute.

Word of warning though – WMI is a bit slow, or so I’ve been told. Now, the slowness is not really noticeable – my prototype app for example was making around 10 WMI queries at startup without noticeable delay. But it is arguably the slower ways to extract this type of information. I have seen many examples of much more optimized code on StackOverflow but frankly I didn’t really. Premature optimization is often a one way ticket to maintenance hell. WMI queries as described above have been fast enough for me, and I don’t really feel like looking for alternatives at the moment – especially since all the data I want can be obtained using the same exact pattern.

Developping Blackberry Apps: Dice Roller

Tuesday, October 27th, 2009

Last week I wrote about developing a simple hello world app for your blackberry. Today I want to go one step further and show you how to make a real world application that actually does something. Of course since we are all learning to use this new API I want to keep it simple, bare bones and straightforward. We can add bells and whistles later.

For now I just wanted to get a handle on using the basic GUI components, and capturing events such as pressing a button. I don’t particularly care how the app will look. I also don’t care about fancy stuff such as detecting the orientation flip in Storm.

What kind of application would fit all these criteria? Simple? Straightforward? No frills? And yet somehow useful. I pondered this for a little while and came up with this: a dice rolling application. You know, something that emulates rolling one or more dice of a certain type. It’s basically a random number generator attached to a GUI front end. And it’s useful too. Well, for me at least. The ability to generate random numbers in your phone comes in handy when you are into pen & paper RPG games like me.

So I drew up a simple design in my mind. The app would essentially have two input fields. One field would accept the number of dice to be rolled, while the other field would accept the type of dice. For those of you who don’t know this: yes, there are many types of dice. The die you usually see in casinos is what we call a d6 – a six sided dice. We role players also use d4, d8, d10, d12 and d20. When needed we also simulate a d100 by rolling two d10’s (you pick one dice to signify the tens and the other the ones).

The user will type in the values into the two fields, press a button and get the results. Simple and easy to develop. The end result should look like this:

Blackberry Dice Roller App

Blackberry Dice Roller App

How do we do this? Let me show it to you. I apologize for the wall of text code segment but the app is just a single class and a fairly short one at that. It really doesn’t make much sense to break this code up. Note that this project uses a driver class just like the one I shown you in the Halo World example. I omitted it here because it is all uninteresting boilerplate code. To actually run this code however, you will need to create one yourself.

import java.util.Random;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.text.NumericTextFilter;
 
 
public class DiceScreen extends MainScreen 
{
   private EditField howmany, dice;
 
   public DiceScreen()
   {
 
      super();
      LabelField applicationTitle = 
        new LabelField("Luke's Dice Roller");
 
      setTitle(applicationTitle);
 
      howmany = 
        new EditField("How Many? ", "2", 10, Field.EDITABLE);
 
      howmany.setFilter(new NumericTextFilter());
      add(howmany);
 
      dice = new 
        EditField("What kind of dice? ", "6", 10, 
        Field.EDITABLE);
 
      dice.setFilter(new NumericTextFilter());
      add(dice);
 
      ButtonField roll = new ButtonField("Roll");
      add(roll);
 
      FieldChangeListener listener = new FieldChangeListener() 
      {
         public void fieldChanged(Field field, int context) 
         {
            int h = Integer.parseInt(howmany.getText());
            int d = Integer.parseInt(dice.getText());
 
            String result = randomize(h, d);
            Dialog.alert("Results: " + result);  
         }
      };
 
      roll.setChangeListener(listener);
   }
 
   private String randomize(int howmany, int dice)
   {
      String out = "";
      Random generator = new Random();
 
      for(int i=0; i<howmany; i++)
      {
         int temp = generator.nextInt(dice) +1;
         out += temp + ", ";
      }
 
      return out;
   }
 
}

Very straightforward stuff. The EditField component is basically a combination of a label and input box. Instead of using two components you just do one, and it accepts a string argument that will display some text to the left of the input box. It also accepts the initial value, maximum length and style indicator (in that order).

Each EditField (or rather each Field) defines a setFilter method that lets you pass in a filter object that will prohibit imputing certain values. I’m passing in a NumericTextFilter object which is why the Blackberry Storm displays the numeric keyboard when that field is active.

Finally, I create a listener for my button by defining FieldChangeListener instance as an inner class. I then attach it to my button just like I would do it a Swing application.

I don’t think I need to explain the random number generation procedure, since that’s something you should already know how to do. If you don’t, I recommend cracking open any Java book, or online tutorial. Random number stuff will probably be like on page 3 or something.

To keep things simple, I made the results appear in a modal dialog:

Blackberry Dice Roller in Action!

Blackberry Dice Roller in Action!

It works! Happy dance!

Of course this app has some serious problems. For one, it is ugly as hell. At least compared to most native Storm applications. It is also infuriatingly hard to navigate using the touch screen. You can’t really see this in the emulator, but once you load this ting onto your phone, changing fields becomes frustrating. Because they are so close, a downward finger swipe will almost always skip the second field and highlight the button. And upward swipe on he other hand will highlight the first field. Getting to the second field is then a matter of careful finger placement.

This is an usability issue that needs to be resolved before this little simplistic app can be considered worth while. So this is what I want to talk about in the next post in this series. Adding bells and whistles. I want to make this app look pretty, and somehow space the fields out so that they can be easily navigated.

I’d also like to do something fancy – for example remove the button and attach the dice rolling action to the orientation switch event. This way you could actually roll the dice with a flick of your wrist. How awesome would that be? Of course it would require some testing to see how sensitive the device really is, and whether or not the roll would be accidentally t triggered during normal use.

Developping Blackberry Apps: Hello World

Tuesday, October 20th, 2009

I almost forgot about this post. It got stuck in the draft queue for a few weeks now, but since I’m running low on postable content, I decided to resurrect it, clean it up and post it.

As promised, I wanted to show you how to create a simple Blackberry application in Java. Of course since this is Java, we will be typing way more than it is logically necessary. For example, a simple Hello World application requires no less than two classes, with a full complement of boring boilerplate code. If you are a long time Java programmer you probably just went “Only two? Phew! I thought it was worse”.

Our first class is basically there just to hold the main function, because that’s what you do in Java. You create a class, then you declare your main function, and then you writhe your procedural code inside:

import net.rim.device.api.ui.UiApplication;
 
public class HelloWorld extends UiApplication
{
	public HelloWorld()
	{
		pushScreen(new HelloScreen());
	}
 
	public static void main(String[] args)
	{
		HelloWorld instance = new HelloWorld();
		instance.enterEventDispatcher();
	}
}

There are two things here that might require explanation. The pushScreen method takes an UI container as a parameter and then paints it on screen. In our case this container is going to be a class extending net.rim.device.api.ui.container.MainScreen – I will show you how to create one in just a second.

The enterEventDispatcher method enters the main loop and handles capturing and dispatching events. The rest should be self explanatory.

Now for the actual GUI container:

import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
 
public class HelloScreen extends MainScreen
{
	public HelloScreen()
	{
		super();
		LabelField applicationTitle = 
			new LabelField("My First Applicaiton");
		setTitle(applicationTitle);
 
		LabelField hello = 
			new LabelField("Hello World!");
		add(hello);
	}
}

As you can see, blackberry apps are built just like any other Java GUI apps. You initialize container, label, field and button objects, you add them to each other creating hierarchies. There are some layout classes that can help you out and if you need to capture events you attach a listener to an object just like you would do it in Swing app. This is how our app looks like in the emulator:

A simple hello world app is not very pretty too look at. Click to embigen.

A simple hello world app is not very pretty too look at. Click to embigen.

It’s simple and kinda ugly, but that’s really all we were going for. It is remarkably easy to create simple, create apps this way. You will however quickly notice that slapping few fields and labels together may work OK for other blackberry models, but is not the best way to make an app for the storm. Because of the way the interface works, it can be sometimes difficult to switch between fields that are very close to each other. Designing usable and good looking Storm apps takes a little practice. But more on that later..