Partilhar via


AppDomain and Shadow Copy

.Net Framework has a feature called Shadow Copy. When shadow copy is enabled on an appdomain, assemblies loaded in that appdomain will be copied to a shadow copy cache directory, and will be used from there. This is great because the original file is not locked. So it can be changed at will. ASP.NET uses this extensively. Actually, shadow copy is enabled on every appdomain created by ASP.NET.

 

This feature is implemented by fusion.

 

Unfortunately the documentation for shadow copy is rather poor. MSDN has documentation on various things affecting shadow copy. But it does not discuss the detail of shadow copy feature. This post is an attempt to discuss in detail how shadow copy works.

 

All the discussion is based on AppDomainSetup class unless specified.

 

There are three things affecting shadow copy:

  1. How to enable shadow copy?

  2. What will be shadow copied?

  3. Where do shadow copied bits go?

     

1. How to enable shadow copy?

MSDN says it all. Set AppDomainSetup.ShadowCopyFiles to true will enable shadow copy.

 

2. What will be shadow copied?

AppDomainSetup.ShadowCopyDirectories controls what will be shadow copied. It is a list of directory names, separated by a semicolon. Each directory name should be absolute directory path. Assemblies loaded from those directories will be shadow copied. If ShadowCopyDirectories is null, all assemblies will be shadow copied. (An interesting corner case is what if ShadowCopyDirectories is empty string. I’ll leave this as an exercise for the readers. What do you think the behavior will be?)

 

3. Where do shadow copied bits go?

AppDomainSetup.CachePath + AppDomainSetup.ApplicationName control where shadow copied bits go. If both CachePath and ApplicationName are set, shadow copied bits will go to CachePath\ApplicationName. Otherwise shadow copied bits will go to your download cache (which is stored in %userprofile%\local settings\application data\assembly). The combination of CachePath and ApplicationName is really handy for ASP.NET, because they can set a common CachePath, and have each application shadow copy to a different location.

You are responsible to clean up the shadow copy cache if you set CachePath+ApplicationName. In the case of download cache as shadow copy cache, it is automatically managed by fusion.

 

On the default appdomain you cannot change its AppDomainSetup. But you can use AppDomain’s API to change the properties. The relevant APIs are:

SetCachePath, SetShadowCopyFiles, SetShadowCopyPath (the name of this one is not consistent with AppDomainSetup.ShadowCopyDirectories). The ApplicationName is set to the name of the application on default domain.

Comments

  • Anonymous
    February 09, 2004
    Thanks for the info, keep it coming. On the empty string question, I'd guess that nothing would be copied since it would not locate a directory whose name was an empty string.

    A question about the shadow copy directories; you state that each directory must be specified as an absolute path. This implies that assemblies will be shadow copied regardless of their original location on the machine, or will this only affect files from subdirectories at or below the appbase? If it's from anywhere then does this mean that assemblies loaded using LoadFrom or LoadFile as opposed to Load will also be shadow copied? In other words, does the fusion load context have an effect on assemblies that are shadow copied? Thanks.

    Dave


  • Anonymous
    February 09, 2004
    David,

    Regarding the exercise, yes, you are correct. Nothing will be copied.

    You are correct about the LoadFrom also. Shadow copy will be applied to both Assembly.Load and Assembly.LoadFrom. What we check is that this assembly is from one of those directories. If they are, we shadow copy it.

    But Assembly.LoadFile does not benefit from shadow copy. Because LoadFile does not go throught fusion. Fusion only handles Assembly.Load(string) and Assembly.LoadFrom.

  • Anonymous
    March 08, 2004
    Denis sent a comment using the contact link. Please use the comment to post question. Other people may be interested in the answer.

    Shadow Copy in AppDomain is not the same as Volume Shadow Copy feature in Windows Server 2003. We don't keep track of history. It is mainly a workaround to not lock the original file.

    Sender: Denis AUGER
    Email: auger_denis@emc.com
    =====================================
    Hi,

    I have found in the API how to active a Volume Shadow Copy with appDomain class.

    But I need, through the API, to get all the "previous versions" giving a file name.
    I also need to launch a restore of a file or a directory.

    Do you know how is it possible through the API ?

    Thank's very much for your help

    Denis

  • Anonymous
    April 29, 2004
    The comment has been removed

  • Anonymous
    July 02, 2004
    I have the following problem:
    I followed the steps described here, as well as anywhere i looked for documentation regarding this issue and the result is not quite what I expected. I obtain a shadow copy of my dll, but both files, the original and the shadow copied dll are locked by the process.
    here is a piece of the code, please tell me what is wrong with it:

    System.AppDomainSetup appDomainSetup = new AppDomainSetup();

    appDomainSetup.ShadowCopyDirectories = "D:\pathToMyApp\bin\Debug";
    appDomainSetup.ShadowCopyFiles = "true";
    appDomainSetup.CachePath = @"D:\pathToMyApp\bin\Debug";
    appDomainSetup.ApplicationName = "appName";

    System.AppDomain appDomain = System.AppDomain.CreateDomain("Domain" + "someName",
    new System.Security.Policy.Evidence(AppDomain.CurrentDomain.Evidence),
    appDomainSetup);

    System.Reflection.AssemblyName assemblyName = System.Reflection.AssemblyName.GetAssemblyName("pathToTheDll");

    System.Reflection.Assembly assembly = appDomain.Load(assemblyName);

  • Anonymous
    July 03, 2004
    Please see Suzanne'blog about AppDomain.Load()
    http://blogs.msdn.com/suzcook/archive/2003/06/16/57188.aspx

  • Anonymous
    July 07, 2004
    Assembly.Unload

  • Anonymous
    August 12, 2006
    PingBack from http://www.livejournal.com/users/sunnywizmudding/4884.html

  • Anonymous
    August 12, 2006
    PingBack from http://www.ljseek.com/shadow-copies-of-assemblies_709543.html

  • Anonymous
    August 31, 2007
    http://www.blogcn.com/user8/flier_lu/index.html?id=2164751

  • Anonymous
    July 08, 2008
    PingBack from http://aaliyah.onlinevidsworld.info/shadowcopy.html

  • Anonymous
    January 17, 2009
    PingBack from http://www.hilpers.com/1174545-appdomain-shadowcopy

  • Anonymous
    February 09, 2009
    PingBack from http://kapustein.com/blog/?p=1170