delegating uninstallation of assembly file : *** to Fusion
Summary: I created a MSI package which has Merge Module - Microsoft_VC90_DebugCRT_x86.msm. I was able to install the MSI package successfully on my WIN 7 OS. Then I uninstalled the same MSI successfully but the file msvcr90d.dll was NOT removed from the directory: C:\windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\
But if I keep the system idle for few minutes, the file gets removed automatically. I took a procmon trace after the MSI uninstall and found that the file msvcr90d.dll was deleted by C:\windows\servicing\TrustedInstaller.exe
As per the MSI uninstall log:
MSI (s) (E4:50) [12:27:46:952]: Executing op: ActionStart(Name=RemoveFiles,Description=Removing files,Template=File: [1], Directory: [9])
MSI (s) (E4:50) [12:27:46:955]: Executing op: ProgressTotal(Total=22,Type=1,ByteEquivalent=175000)
MSI (s) (E4:50) [12:27:46:956]: Executing op: SetTargetFolder(Folder=C:\windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\)
MSI (s) (E4:50) [12:27:46:957]: Executing op: FileRemove(,FileName=msvcr90d.dll,,ComponentId={F5DEC4D5-A8A3-3883-B311-C6227A0D21AD})
MSI (s) (E4:50) [12:27:46:967]: delegating uninstallation of assembly file : msvcr90d.dll to Fusion
As per the procmon trace:
TrustedInstaller.exe 3336 QueryDirectory C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668 SUCCESS 0: msvcr90d.dll
TrustedInstaller.exe 3336 SetDispositionInformationFile C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668 SUCCESS Delete: =True
As far as Windows Installer is concerned it did the right thing. MSI doesn’t remove the file itself. Instead it calls into the fusion asking it to uninstall the assembly. The above lines mean that we have marked the assembly as removable from MSI's viewpoint and asked fusion to remove the file when the transaction is completed and changes committed to the machine. It means that the fusion didn’t delete the file when requested as the component store performs lazy cleanup to speed up uninstall. This is by design and the concept is called “scavenging”. The key point is that even the binary file (msvcr90d.dll) is still present after uninstall, it isn’t available for binding by other applications. So there wouldn’t be any impact due to this behavior. For more information on Scavenging, please go through this blog post . [the directory may hold on to recently-installed or soon-to-be-installed files until they are installed or scavenged in bulk. Scavenging happens periodically, but it cannot be controlled or induced. It is important to note then, that uninstalling a Side-by-Side assembly may not immediately remove the associated files from the WinSxS directory. This is expected, and not a violation of Windows Logo requirements for clean uninstall.]
You can observe that the binaries are indeed uninstalled, even before they are scavenged, by checking for install state with the tool checkruntimes.exe: https://blogs.msdn.com/b/talagrand/archive/2010/03/02/9973115.aspx
Once the MSI is uninstalled successfully, we found that the file msvcr90d.dll was not removed physically from C:\windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\ but you can run the below command to know the actual install state of the binary:
After the MSI package is installed
C:\Users\Administrator>C:\checkruntimes\checkruntimes.exe -x86 -crt -9
DebugCRT x86 v9.0.30729.6161 is installed
CRT x86 v9.0.30729.4940 is installed
After the MSI package is uninstalled
C:\Users\Administrator>C:\checkruntimes\checkruntimes.exe -x86 -crt -9
CRT
x86 v9.0.30729.4940 is installed
The binary msvcr90d.dll is not listed above.
#When called with no arguments, it lists runtimes it can find – calling checkruntimes.exe with no arguments is equivalent to calling: checkruntimes.exe -8 -9 -10 -debug -retail -x86 -x64 -ia64 -crt -atl -openmp -mfc