在 C# 中动态替换 DLL

Posted

技术标签:

【中文标题】在 C# 中动态替换 DLL【英文标题】:Replace DLL dynamically in C# 【发布时间】:2014-01-12 11:03:39 【问题描述】:

我使用VCProjectEngine.dllVisual Studio 2010Visual Studio 2012 有两个版本。 我想替换DLL 版本动态我会卸载旧版本,然后加载新的DLL

我从this post 了解到,我无法卸载DLL,而是卸载所有。 所以我尝试卸载域:

AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
AppDomain domain = AppDomain.CreateDomain("MyDomain", adevidence, domaininfo);

AppDomain.Unload(domain);

现在我尝试加载新的DLL 版本:

AppDomain.CurrentDomain.Load(new AssemblyName("Microsoft.VisualStudio.VCProjectEngine, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"));

但它没有帮助,Visual Studio 2012 不知道 VCProject 类型,因为旧版本不适合它。

我的代码有什么问题?或者也许还有其他方法可以以编程方式替换DLL

【问题讨论】:

请注意,您不应为此目的使用 AppDomain.Load。看看这个关于如何在特定 AppDomain ***.com/a/17324102/850119 中加载程序集的答案。 【参考方案1】:

正如您所说,您无法卸载 DLL - 您可以卸载应用程序域。

但是,为了卸载应用程序域,您需要在要卸载的域中加载 DLL。在您的示例中,您正在卸载一些应用程序域,然后将 DLL 加载到应用程序的默认域中。

您应该在该域中加载 DLL,并在那里调用它的方法。请注意,您需要所有的返回值和参数都是可序列化的,因为它们将被编组。这也意味着您的 DLL 公开的对象应该是 MarshalByRef 对象。

【讨论】:

所以,我需要将AppDomain.CurrentDomain.Load 替换为domain.Load 是的。并且您需要跨域边界调用 DLL。 我如何调用 DLL?我只想声明 DLL 中存在的静态接口类型,例如 VCProject pro=solution.Projects.Item(1).Object; 您在 DLL 中创建一个类的实例。这就是我所说的“调用 DLL”。对该实例的所有访问都将跨越域边界。 问题是这些类型存在于旧dll和新dll中,调试器采用旧dll中出现的类,而不是新dll。

以上是关于在 C# 中动态替换 DLL的主要内容,如果未能解决你的问题,请参考以下文章

C#中如何调用动态链接库DLL

怎么在C#中添加用C语言开发的动态链接库dll文件(vs2010)?

C#中动态加载和卸载DLL

在 C# 中动态加载和使用 DLL

C#中如何动态加载和卸载DLL

C# 动态调用DLL库