Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Product Code of installed Msi

I have a C# program where I have to get the product code of an installed msi. I have only the msi name as the input. Can this be done programmatically?

like image 878
Sandeep Avatar asked Jun 14 '11 14:06

Sandeep


3 Answers

Do the answers to this question help? They want to get the product name, but maybe it works for the product code, too?

EDIT
If you do not have the MSI file itself to access the database (as suggested by the above link to the other question), you may try to search the following registry path for the name of your MSI file:

HKEY_CLASSES_ROOT\Installer\Products\*\SourceList 

There are many entries under the Products branch. Each of them is a product key. Every branch should contain the SourceList node, which in turn should contain the value PackageName. That value holds the name of the MSI file.

So what I'd do is:

for each key in Products
{
    open SourceList subkey
    read PackageName value
    if name equals my msi file name
    {
        return key-name formatted as GUID
    }
}
like image 129
Thorsten Dittmar Avatar answered Nov 11 '22 16:11

Thorsten Dittmar


This is the code I used to get the UninstallString of any MSI.

private string GetUninstallString(string msiName)
{
    Utility.WriteLog("Entered GetUninstallString(msiName) - Parameters: msiName = " + msiName);
    string uninstallString = string.Empty;
    try
    {
        string path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products";

        RegistryKey key = Registry.LocalMachine.OpenSubKey(path);

        foreach (string tempKeyName in key.GetSubKeyNames())
        {
            RegistryKey tempKey = key.OpenSubKey(tempKeyName + "\\InstallProperties");
            if (tempKey != null)
            {
                if (string.Equals(Convert.ToString(tempKey.GetValue("DisplayName")), msiName, StringComparison.CurrentCultureIgnoreCase))
                {
                    uninstallString = Convert.ToString(tempKey.GetValue("UninstallString"));
                    uninstallString = uninstallString.Replace("/I", "/X");
                    uninstallString = uninstallString.Replace("MsiExec.exe", "").Trim();
                    uninstallString += " /quiet /qn";
                    break;
                }
            }
        }

        return uninstallString;
    }
    catch (Exception ex)
    {
        throw new ApplicationException(ex.Message);
    }
}

This will give a result like this:

MsiExec.exe /I{6BB09011-69E1-472F-ACAD-FA0E7DA3E2CE}

From this string, you can take the substring within the braces {}, which will be 6BB09011-69E1-472F-ACAD-FA0E7DA3E2CE. I hope this might be the product code.

like image 5
Sandeep Avatar answered Nov 11 '22 16:11

Sandeep


There is most fast and simply way - to use WMI with conditional query string.

    public string GetProductCode(string productName)
    {
        string query = string.Format("select * from Win32_Product where Name='{0}'", productName);
        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
        {
            foreach (ManagementObject product in searcher.Get())
                return product["IdentifyingNumber"].ToString();
        }
        return null;
    }
like image 3
Vladimir Shiyanov Avatar answered Nov 11 '22 14:11

Vladimir Shiyanov