Poul K. Sørensen
Poul K. Sørensen

Reputation: 17540

Release the lock on dlls picked up by MEF in a click once application

How do I enable in my ClickOnce Application (WPF) such plugin dlls can be delted at runtime?

I have found an old demo that do it with this.

private static void SetShadowCopy()
{
    AppDomain.CurrentDomain.SetShadowCopyFiles();
    AppDomain.CurrentDomain.SetCachePath(@"C:\MEF\PartUpdatesInPlace\PartUpdatesInPlace\bin\Debug\Cache");
}

But it yields warnings that it is obsolete and I should use something else but I cant figure out how to enable shadow copying when not doing like above. The two lines works as expected. And I have seen people doing a shell exe application that startst he real application. I dont want that either.

I assume there must be a way to do the same as above but not using obsolete methods.

Update

        // Works
        AppDomain.CurrentDomain.SetShadowCopyFiles();
        AppDomain.CurrentDomain.SetCachePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Cache\");
     
        // Dont Work
        AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";
        AppDomain.CurrentDomain.SetupInformation.CachePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Cache\";
      

The difference seems to be that SetShadowCopyFiles() works from the point its called and after, so when I setup the Mef Catalogs after this calls the dlls works and I can update dlls and do a container.refresh() without problems.

Using SetupInformation no cache folder is created and the dlls are locked.

Update 2

To others. This dont work for click once applications so far.

Upvotes: 3

Views: 424

Answers (1)

TyCobb
TyCobb

Reputation: 9089

According to MSDN, the alternative to SetShadowCopyFiles() is IAppDomainSetup.ShadowCopyFiles {get;set;}

You should just be able to set it to true and give the same functionality.

To use it, set the ShadowCopyFiles property on the SetupInformation. AppDomain.ShadowCopyFiles is read-only.

AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";

EDIT: It appears as though changing the SetupInformation after the domain has been created has no effect.

AppDomainSetup Class: Changing the properties of an AppDomainSetup instance does not affect any existing AppDomain. It can affect only the creation of a new AppDomain, when the CreateDomain method is called with the AppDomainSetup instance as a parameter.

I am unsure how you are supposed to do it now other than continuing with the obsolete methods and risking the fact that the next iteration of .NET may remove them.

EDIT 2: I played around with this a little bit and used dotPeek to see what the AppDomain was doing with the ShadowCopyFiles. I decided to see if I could set it through Reflection.

You may want to try the below and see if this does what you need. Setting it to true on the internal FusionStore property of AppDomain causes the AppDomain.ShadowCopyFiles property to reflect the change which was not the case when setting it on the exposed SetupInformation.ShadowCopyFiles property.

var setupInfoProperty = AppDomain.CurrentDomain.GetType().GetProperty("FusionStore", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance);
var setupInfo = (AppDomainSetup) setupInfoProperty.GetValue(AppDomain.CurrentDomain);
setupInfo.ShadowCopyFiles = "true";
setupInfo.CachePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Cache\";

Upvotes: 1

Related Questions