How can I list the GUID of an installed program in Windows? Alternatively, is it easier to find the GUID if I have the MSI file?
I'm looking through the MSI file with Orca but not sure where to look to find the GUID.
Thanks!
How can I list the GUID of an installed program in Windows? Alternatively, is it easier to find the GUID if I have the MSI file?
I'm looking through the MSI file with Orca but not sure where to look to find the GUID.
Thanks!
The three main GUIDs of a Windows Installer database are the Package Code, ProductCode, and UpgradeCode. The first is stored in the summary information stream (View menu in Orca), and the others are stored in the Property table. (Other forms of databases such as merge modules and patches have similar GUIDs in similar places, such as the merge module's GUID or the patch code GUID - each stored identically to the package code.)
To find them on a machine, you can look in the Uninstall key, where the ProductCode is often used. Or better yet, if you are looking to enumerate what is currently installed on the machine, you can call MsiEnumProducts.
There are several ways to locate the product GUID for installed packages. Please prefer option number 3.
The most common are:
- 32-BIT SECTION:
HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall (per user section)
- 64-BIT SECTION:
HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
- MERGED SECTION (supposedly all of the above merged together, I have not verified):
HKCR\Installer\Products
If what you are trying to do is to uninstall the product in question, see this comprehesive uninstall MSI answer: Uninstalling an MSI file from the command line without using msiexec
If you feel more comfortable using VBScript instead of Powershell, please try this answer from Phil Wilson: how to find out which products are installed - newer product are already installed MSI windows
Typically (though not universally) if a piece of software uses MSI-based installation the GUID can be found in the Uninstall entry. It will usually either be the key name or will appear in the UninstallString and/or UninstallPath value. Sometimes life is easy and there is a ProductGuid value.
Uninstall entries can be found here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
On a 64-bit version of Windows there are two such keys, one for 64-bit software and a second for 32-bit software:
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
My solution is that I wrote a small console app which returns ProductCode of any MSI file (name is passed as program argument). I'm doing it by reading the guid from .msi file itself. Basically I'm opening that msi file as a string and looking for a text started with "ProductCode", getting its index and taking 38-chars before that index position. Here is the screenshot:
if you just want to know what ProductName and ProductCode (ProductId) a given MSI contains, without installing that MSI and checking the registry, you can query the MSI itself with PowerShell using a function like this (inspired by http://www.scconfigmgr.com/2014/08/22/how-to-get-msi-file-information-with-powershell):
function Get-MSIProperties {
param (
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.IO.FileInfo] $path,
[string[]] $properties = @('ProductCode', 'ProductVersion', 'ProductName', 'Manufacturer', 'ProductLanguage')
)
begin {
$windowsInstaller = (New-Object -ComObject WindowsInstaller.Installer)
}
process {
$table = @{}
$msi = $windowsInstaller.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $windowsInstaller, @($Path.FullName, 0))
foreach ($property in $properties) {
try {
$view = $msi.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $msi, ("SELECT Value FROM Property WHERE Property = '$($property)'"))
$view.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $view, $null)
$record = $view.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $view, $null)
$table.add($property, $record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 1))
}
catch {
$table.add($property, $null)
}
}
$msi.GetType().InvokeMember('Commit', 'InvokeMethod', $null, $msi, $null)
$view.GetType().InvokeMember('Close', 'InvokeMethod', $null, $view, $null)
$msi = $null
$view = $null
return $table
}
end {
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($windowsInstaller) | Out-Null
[System.GC]::Collect()
}
}