Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

Uninstalling applications programmatically (with WMI)

4.80/5 (10 votes)
23 Aug 2012CPOL3 min read 74.6K   2.3K  
Uninstall applications with WMI

Introduction

Recently I was faced with the challenge of uninstalling an application programmatically. I had scoured the internet only to find a large amount of developers taking the registry key approach (finding the uninstall string then shelling to Windows installer). This however has its disadvantages…this uninstall string is located in different areas depending on your Windows build and architecture (x86 or x64). I decided to do a little research with Windows Management Instrumentation (WMI) and came up with the following solution.

Using the code

The first step is to add a COM reference to System.Management, adding the namespace is not enough, the COM reference contains the classes we will use.

C#
using System.Management

Listing installed applications

Next, let's get a collection of applications that are installed on the system (note that some items may show up in Win32_Product that don't actually have an uninstall string and are not listed in add/remove programs, i'm unsure why...)

The first step in achieving this is by creating a ManagementObjectSearcher which Retrieves a collection of management objects based on a specified query, our query is based on the Win32_Product class:

C#
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");

After the query has been set the command needs to be executed, to do so we call the ManagementObjectSearcher Get() function (which we initiated as mos):

*Take note that the Get() method is resource intensive and may take a bit to return*

C#
foreach (ManagementObject mo in mos.Get())
{
 ///

Since the Get() statement is IEnumerable we can enumerate its contents in a for loop, exposing each ManagementObject. We are simply looking for the "Name" property (you can find others on the MSDN site: http://msdn.microsoft.com/en-us/library/windows/desktop/aa394378(v=vs.85).aspx )

We get a ManagementObject property by using the following format:

C++
mo["Name"].ToString()

Since it is an Object, we need to convert it to a string (which is the [Name] data type), this is very simple in C#.

The full block of code to list installed applications:

C#
using System.Management
private List<string> ListPrograms()
{
    List<string> programs = new List<string>();

    try
    {
        ManagementObjectSearcher mos = 
          new ManagementObjectSearcher("SELECT * FROM Win32_Product");
        foreach (ManagementObject mo in mos.Get())
        {
            try
            {
                //more properties:
                //http://msdn.microsoft.com/en-us/library/windows/desktop/aa394378(v=vs.85).aspx
                programs.Add(mo["Name"].ToString());

            }
            catch (Exception ex)
            {
                //this program may not have a name property
            }
        }

        return programs;

    }
    catch (Exception ex)
    {
        return programs;
    }
}

Now that we have a list of installed applications we should be able to pass the [Name] property to our uninstall method.

Uninstalling an application

Now it's time to uninstall. Note that the uninstall method is pretty much the same as our method to enumerate and list installed applications, the only difference here is we now need to Invoke the Win32_Product method to “Uninstall” (there are a list of other available methods in the link above).

The query has also changed. Now that we know the name of the application, we do not need to enumerate the entire list of applications installed:

SQL
"SELECT * FROM Win32_Product WHERE Name = '" + ProgramName + "'"

Here is the entire block to uninstall an application, I'll get in detail after you take a look.

C#
 private bool UninstallProgram(string ProgramName)
{
    try
    {
        ManagementObjectSearcher mos = new ManagementObjectSearcher(
          "SELECT * FROM Win32_Product WHERE Name = '" + ProgramName + "'");
        foreach (ManagementObject mo in mos.Get())
        {
            try
            {
                if (mo["Name"].ToString() == ProgramName)
                {
                    object hr = mo.InvokeMethod("Uninstall", null);
                    return (bool)hr;
                }
            }
            catch (Exception ex)
            {
                //this program may not have a name property, so an exception will be thrown
            }
        }

        //was not found...
        return false;

    }
    catch (Exception ex)
    {
        return false;
    }
}

After the search is executed with mos.Get() we will have a list (most likely just 1 instance) of the chosen application to uninstall (You can see that I placed a simple safety net of comparing the application about to be uninstalled with the actual application we want to remove). Now lets focus on the method that actually uninstalls the application:

C#
object hr = mo.InvokeMethod("Uninstall", null);

Note: ManagementObject.Invoke() requires Full trust for the immediate caller. This member cannot be used by partially trusted code, so you should be an administrator or add a manifest to your application with “requireadministrator” set.

Now that our ManagementObject is set to an instance of the application we want to uninstall we need to invoke the Win32_Product class' “Uninstall”. Above I demonstrated on how to call this synchronous method (the second parameter in InvokeMethod() is to pass any parameters, which "Uninstall" takes nothing, thus null... There are several more overloads). Cast hr to a boolean value to get the results returned.

That's it!

Take note that the attached code contains a BackgroundWorker that prevents the UI locking up during the WMI search (which I do not cover here), yes, this search is resource intensive and may take a bit to list applications depending on your system specs...

Points of interest

After facing trial and error I have successfully used this code in my own personal projects to uninstall my applications during certain update scenarios… I have found this method more reliable than looking for registry keys that contain the applications Uninstall string.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)