I would like to know what MSI installed a given dll or exe on my system. I know that Windows fixes deleted files if they belong to an installed package. Can I query that information without actually deleting the file? Is there a tool or Win32 API to check what package a file belongs to?
It appears like there might be a way after all! I recently discovered registry entries for files installed by Windows Installers under the following subtree:
I wrote a small Python script to lookup the installer for a file using the information stored there:
> python windows-installer-file-search.py opus.dll File: C:\Program Files (x86)\Mumble\opus.dll Product: Mumble 1.2.13 Install user: S-1-5-18 Cached installer: C:\Windows\Installer\2f6b072.msi
It is available here: https://github.com/Zero3/windows-installer-file-search
Wow. 2.5 years later you nailed this question. Looking at that subtree, now I understand why it takes so much time to boot up Windows. This has to be indexed in memory for the "your application is corrupt, insert disk" feature to work on every execution of an application. Jan 28, 2016 at 19:27
If you are okay with just finding plausible needles in the haystack, this quick and dirty abuse of 7-Zip will work:
7z.exe l -an -air!C:\Windows\Installer\*.msi > needlelist.txt
needlelist.txt in any text editor, search for
needlename.dll and you will find the corresponding .msi package in the listings generated by 7-Zip.
(Note: This method is 'dirty' because it just tells you which .msi packages that contains a file named
needlename.dll. But it is probably fine for most use cases.)
Indeed, this is a clever abuse of 7-Zip. Does the installer always copy the MSI to that C:\Windows\Installer folder or is it just a convention that might be circumvented? I am still waiting for an elegant Win32 API before accepting the fact that there is no other way (and accepting your answer). Jul 16, 2013 at 8:04
AFAIK Windows Installer always caches installed MSIs in the folder (also see superuser.com/questions/473569/…). The reason for this is logical: The installer is also the uninstaller. Windows thus needs a copy of the uninstaller in a known location in order to execute it when the user wants to uninstall the application. As the original MSI probably has been deleted ages ago at this point, Windows saves a copy during installation.– Zero3Jul 16, 2013 at 20:50
Regarding an API: Unlike most Linux distros (and the like), Windows (prior to Windows 8, at least) do not have a proper package management system built into the operating system, capable of querying for things like this. One could probably create an application to do this by running through all installed MSIs and search inside them for the target file (essentially my answer implemented properly), but this does not appear to be implemented out-of-the-box. I might be wrong, of course.– Zero3Jul 16, 2013 at 20:58
Well, I accept it as an answer. Although we cannot prove there is no Win32 API for this, my feeling was that MSI somehow hooked into the process loading without a proper public API. Jul 30, 2013 at 11:08