Tuesday, June 28, 2011

Shared DLLs

How Shared DLLs work ( a work in progress )

Files that are directed to do so in an MSI database will place a value name in the Registry here
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs

In the MSI Packaging world the common understanding of "Shared DLLs" that I have come across is:
  1. They are dlls that have been listed in the SharedDLLs key in the registry
  2. They are listed because they may be used by more than one MSI installed application
  3. The regsitry key is created as a DWORD and it is incremented each time an application is installed with the file
  4. They are decremented each time one of these applications are uninstalled
  5. This keeps the shared dll installed until the final application using the noted dll is uninstalled.

Much of this is true but some correction, and further explanation is needed:
  1. Actually the "Shared Dll" is an MSI's Component's file Key Path so it could be any file type really
  2. This is correct
  3. Correct, the value name is set to the file key path and the value data is initially set to 1
  4. Correct
  5. It leaves behind more than the referenced file, in actuality it causes the whole component to stay installed.

In the Component table the Attributes can be set to 8 (the bit flag name is msidbComponentAttributesSharedDllRefCount) to let Windows Installer know to increment the reference count in the Shared DLL registry of the components key file. If the key file already exists in the registry the reference count will be incremented whether this bit is set or not. This can cause orphaned files if the value exists but the package that installed it is no longer installed, this would cause the value data to be one greater than the actual number of installed applications sharing the files.

So I tried a few experiments:
I created a couple of MSI's that installed the same text files to the same directories, and had the same key path for that
componentbut in all other ways they were different.

App 1 component with same keypath but not set as shared dll
App 2 component with same keypath but set as shared dll


When I installed then in this order everything behaved as I expected:
Install App 2 - SharedDLLs value data set to 1 then
Install App 1 - SharedDLLs value data set to 2

When I installed them in the reverse order something strange happened
I expected:
Install App 1 - SharedDLLs value data does not exist then
Install App 2 - SharedDLLs value data set to 1

What I saw was:
Install App 1 - SharedDLLs value data does not exist then
Install App 2 - SharedDLLs value data set to 2
Uninstall App 1 - SharedDLLs value data still set to 2
Uninstall App 2 - SharedDLLs value data still set to 1 and the component files remain

I tried it again this way:
Install App 1 - SharedDLLs value data does not exist then
Install App 2 - SharedDLLs value data set to 2
Uninstall App 2 - SharedDLLs value data set to 1
Uninstall App 1 - SharedDLLs value data still set to 1 and the component files remain

More later, I am too tired to continue with this now.

Oh, and here is a tool that can check the size of the SharedDll Registry Key.

No comments: