buddybubble
buddybubble

Reputation: 1319

Unable to query registry for installed msi files

After windows installs a msi file, it will rename that file, move it to C:\Windows\Installers and write the info on how the file can be found to the registry.

I want to query the registry for that key in order to get the exact location of the installed file. The values I am looking for can be found at: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\

Unfortunately I won't know the exact ID of the installed file, so I'll have to open all the items listed at this location and check the product names.

However when I try to query this part of the registry programmatically, I am unable to see any of the items that should be listed at this place.

This is the code I am using right now (no exception handling etc included):

Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Installer").OpenSubKey("UserData").OpenSubKey("S-1-5-18").OpenSubKey("Products")

How can I query this part of the registry? Any other ideas on how to get the location (and name) of the msi file I am looking for?

Upvotes: 1

Views: 2191

Answers (2)

Christopher Painter
Christopher Painter

Reputation: 55581

Spelunking the registry is not the way to go. Windows Installer provides a Win32 API to access this information. For C#/.NET there is a very nice interop library to encapsulate all of this for you. It's called Microsoft.Deployment.WindowsInstaller and ships with Windows Installer XML (WiX) which can be found on CodePlex.

In this library is a class called ProductInstallation with a static method named GetProducts that wraps the underlying MsiEnumProducts function.

public static IEnumerable<ProductInstallation> GetProducts(
    string productCode,
    string userSid,
    UserContexts context
)

productCode (String) ProductCode (GUID) of the product instances to be enumerated. Only instances of products within the scope of the context specified by the userSid and context parameters will be enumerated. This parameter may be set to null to enumerate all products in the specified context.

userSid (String) Specifies a security identifier

(SID) that restricts the context of enumeration. A SID value other than s-1-1-0 is considered a user SID and restricts enumeration to the current user or any user in the system. The special SID string s-1-1-0 (Everyone) specifies enumeration across all users in the system. This parameter can be set to null to restrict the enumeration scope to the current user. When context is set to the machine context only, userSid must be null. context

(UserContexts)

Specifies the user context.

Upvotes: 1

Rotem
Rotem

Reputation: 21927

First of all, you can just write:

Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products")

There's no need to open each key individually.

Second, I believe you problem might be that you're running the code from a 32-bit assembly on a 64-bit machine, and are trying to access the data found in the 64-bit part of the SOFTWARE key. Instead, you are being rerouted to the Wow6432Node, where the key UserData does not necessarily exist inside Installer.

See this answer for how to read from the 64-bit part in a 32-bit assembly.

Upvotes: 3

Related Questions