tags:

views:

39

answers:

2

Hey all,

I'm trying to get info about installed software on local computers (one is Windows 7 and other XP SP3) and I'm able to do it with VBScript, but not with C#.

Here is the VBScript code:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
Set colSoftware = objWMIService.ExecQuery _
    ("Select * from Win32_Product")

For Each objSoftware in colSoftware
    Wscript.Echo "Name: " & objSoftware.Name
    Wscript.Echo "Version: " & objSoftware.Version
Next

and here is the C# code:

string queryProd = "SELECT * FROM Win32_Product";                
ObjectQuery oQuery = new ObjectQuery(queryProd);
ManagementObjectSearcher searcherProd = new ManagementObjectSearcher(oQuery);
ManagementObjectCollection resultCollection = searcherProd.Get();

foreach (ManagementObject prodVar in resultCollection)
{
    Console.WriteLine("Product Name: {0}, Version: {1}.",
        (prodVar["Name"] == null) ? prodVar["Name"] : "/",
        (prodVar["Version"] == null) ? prodVar["Version"] : "/");
}

The second code snippet (C#) is not working. It doesn't give me any error, it just returns null. The thing is that C# code works flawlessly when I'm using some other WMI class, such as Win32_ComputerSystem, for example. But again, it's not working for Win32_DiskDrive class, also this particular case, etc.

In conclusion, in C#, WMI works only for some classes and in VBScript they all work. So, I'm wondering why is that?

Thanks for the answers.

+1  A: 

This is some code I generated using Microsoft's WMI code generator. It seems to get the data you're after.

You can download the generator here

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher("root\\CIMV2", 
                    "SELECT * FROM Win32_Product"); 

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_Product instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Name: {0}", queryObj["Name"]);
                    Console.WriteLine("Version: {0}", queryObj["Version"]);
                }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
            }
        }
    }
}
dhillis
Wow. It's working. Great, thanks. My guess is that I was missing "root\\CIMV2" namespace.
Dejan
Glad to hear that.
dhillis
Thanks for the link to WMI code generator. It just became a very helpful tool for me. :)
Dejan
Sure. I found that tool extremely useful when I was trying to get at WMI data. Have fun with it.
dhillis
A: 

Another C# code that is working in my case is the following:

ManagementClass mgmt = new ManagementClass("Win32_Product");
ManagementObjectCollection objCol = mgmt.GetInstances();
foreach (ManagementObject obj in objCol)
{
    Console.WriteLine("Product Name: {0}, Version: {1}.",
        obj.Properties["Name"].Value.ToString(),
        obj.Properties["Version"].Value.ToString());                    
}

Hope that it will help someone.

Dejan