释放MEF在点击一次应用程序时获取的dll上的锁定

时间:2013-12-18 20:38:13

标签: c# wpf

如何在我的ClickOnce应用程序(WPF)中启用这样的插件dll可以在运行时删除?

我找到了一个旧的演示,用这个来做。

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

但是它会产生警告,它已经过时了,我应该使用别的东西,但我不知道如何在不做上述情况时启用阴影复制。 这两条线按预期工作。我已经看到有人在做一个shell exe应用程序,它开始实际应用。我也不想要那个。

我认为必须有一种方法可以像上面那样做,但不能使用过时的方法。

更新

        // 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\";

差异似乎是SetShadowCopyFiles()从它被调用的点开始工作,所以当我在调用dll之后设置Mef目录时,我可以更新dll并执行container.refresh()而不会出现问题。

使用SetupInformation不会创建缓存文件夹,并且dll会被锁定。

更新2

致别人。到目前为止,这对于单击一次应用程序不起作用。

1 个答案:

答案 0 :(得分:1)

根据MSDN,SetShadowCopyFiles()的替代方法是IAppDomainSetup.ShadowCopyFiles {get;set;}

您应该只能将其设置为true并提供相同的功能。

要使用它,请在SetupInformation上设置ShadowCopyFiles属性。 AppDomain.ShadowCopyFiles是只读的。

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

编辑:看起来好像在创建域后更改SetupInformation无效。

  

AppDomainSetup类:更改AppDomainSetup的属性   实例不会影响任何现有的AppDomain。它只能影响   当CreateDomain方法是时,创建一个新的AppDomain   使用AppDomainSetup实例作为参数调用。

我不确定你现在应该怎么做,除了继续使用过时的方法,并担心.NET的下一次迭代可能会删除它们。

编辑2:我玩了一下这个并使用dotPeek来查看AppDomain使用ShadowCopyFiles做了什么。我决定看看我是否可以通过Reflection进行设置。

您可能需要尝试以下操作,看看这是否符合您的需要。在AppDomain的内部FusionStore属性上将其设置为true会导致AppDomain.ShadowCopyFiles属性反映更改,而在公开的SetupInformation.ShadowCopyFiles属性上设置它时不会发生这种情况。

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\";