Shadow Copying Assemblies
Updated: September 2009
Shadow copying allows assemblies that are used in an application domain to be updated without unloading the application domain. This is particularly useful for applications that must be available continuously, such as ASP.NET sites.
The common language runtime locks an assembly file when the assembly is loaded, so the file cannot be updated until the assembly is unloaded. The only way to unload an assembly from an application domain is by unloading the application domain, so under normal circumstances, an assembly cannot be updated on disk until all the application domains that are using it have been unloaded.
When an application domain is configured to shadow copy files, assemblies from the application path are copied to another location and loaded from that location. The copy is locked, but the original assembly file is unlocked and can be updated.
The only assemblies that can be shadow copied are those stored in the application directory or its subdirectories, specified by the ApplicationBase and PrivateBinPath properties when the application domain is configured. Assemblies stored in the global assembly cache are not shadow copied.
The following list describes how to use the properties of the AppDomainSetup class to configure an application domain for shadow copying.
Enable shadow copying by setting the ShadowCopyFiles property to the string value "true".
By default, this causes all assemblies in the application path to be copied to a download cache before they are loaded. This is the same cache maintained by the common language runtime to store files downloaded from other computers, and the common language runtime automatically deletes the files when they are no longer needed.
Optionally set a custom location for shadow copied files using the CachePath property and the ApplicationName property. The base path for the location is formed by concatenating the ApplicationName property to the CachePath property as a subdirectory. Assemblies are shadow copied to subdirectories of this path, not to the base path itself.
If you specify a custom location, you are responsible for cleaning up the directories and copied files when they are no longer needed. They are not deleted automatically.
There are a couple of reasons why you might want to set a custom location for shadow copied files. You might need to set a custom location for shadow copied files if your application generates a large number of copies. The download cache is limited by size, not by lifetime, so it is possible that the common language runtime will attempt to delete a file that is still in use. Another reason to set a custom location is when users running your application do not have write access to the directory location the common language runtime uses for the download cache.
Optionally limit the assemblies that are shadow copied by using ShadowCopyDirectories property.
When you enable shadow copy for an application domain, the default is to copy all assemblies in the application path — that is, in the directories specified by the ApplicationBase and PrivateBinPath properties. You can limit the copying to selected directories by creating a string containing only those directories you want to shadow copy, and assigning the string to the ShadowCopyDirectories property. Separate the directories with semicolons. The only assemblies that are shadow copied are the ones in the selected directories.
Directory paths must not contain semicolons, because the semicolon is the delimiter character. There is no escape character for semicolons.
The AppDomain class has several methods, such as SetShadowCopyFiles and ClearShadowCopyPath, that can be used to control shadow copying on an application domain, but these have been marked obsolete in the .NET Framework version 2.0. The recommended way to configure an application domain for shadow copying is to use the properties of the AppDomainSetup class.