我两天前在微软社区发布了这个问题.我有了一些好主意,做了一些实验,但还是失败了.为了获得更多帮助,我决定在这里发布这个问题.(原职务:Is it possible for a process to load two dll with different versions?)

我开发了一个word all-in应用程序,它是一个dll,可以由word和一些与word兼容的应用程序加载(在这个问题中,我称它为类word应用程序,它们使用相同的ooxml标准).我的加载项使用CEF.net binding cefglue(它反过来使用CEF(chromium嵌入框架))来呈现一些web内容.下面是我的外接程序项目中的一些详细信息.

此加载项的平台目标是Any CPU,由类似word的应用程序加载.启动时,我通过调用Environment.Is64BitProcess判断此加载项是在32位环境还是64位环境中加载的.之后,我为libcef.dll和其他chromium库设置了适当的库路径,这取决于加载外接程序dll的应用程序是64位还是32位.例如,在64位word中,我的加载项加载64位libcef.dll.使用伪代码的一些详细信息:

// Files in cef library folder
// locales/
// swiftshader/
// cef.pak
// cef_100_percent.pak
// cef_200_percent.pak
// cef_extensions.pak
// chrome_elf.dll
// d3dcompiler_47.dll
// devtools_resources.pak
// icudtl.dat
// libcef.dll
// libEGL.dll
// libGLESv2.dll
// ...

private _cefPath;
    
void FindLibraryPath() {
  bool is64BitEnv = Environment.Is64BitProcess;
  SetLibraryAndResourcePath(is64BitEnv); // set _cefPath and other path here
}
    
void InitializeCef() {
  // Load cef library
  // this method use LoadLibraryEx with the flag
  // LOAD_WITH_ALTERED_SEARCH_PATH to load libcef.dll
  CefRuntime.Load(_cefPath);
  // other statements for cef initialization
  ...
}

private void ThisAddIn_Startup(object sender, System.EventArgs e) {
  FindLibraryPath();
  InitializeCef();
}

这在Microsoft Word中运行良好,但不幸的是,这在类似Word的应用程序中出现了一些问题.原因如下:

Libraries my addin loads

myaddin.dll(.net)->头孢胶.dll(.net)->libcef.dll(native dll,版本67)->其他chromium本机dll

Libraries word-like app loads

|-&燃气轮机;myaddin.dll(.net)->cefglue.dll(.net)->libcef.dll(native dll,版本67)->其他chromium本机dll

(->代表loads|代表加载DLL的独立可能路径)

我使用绝对路径加载libcef.dll,如果我先加载这个库,这个类似word的应用程序不会加载它自己的libcef.dll(LoadLibraryEx的内置规则?),它计划使用我的libcef.dll然后崩溃,毕竟它需要87版.如果word like应用程序先加载libcef.dll,我的加载项将不会加载版本67 libcef.dll,那么我会得到version mismatch异常.

总而言之,我需要的是将相同名称但不同版本libcef.dll与类似应用程序的单词隔离开来,使其无法感知我的加载项加载的同名DLL.一些 idea ?谢谢

推荐答案

这是不可能实现的,因为libcef.dll在依赖项中有其他dll,您无法控制它们的加载.详见Dynamic-Link Library Search Order.该页面的重要部分是:

  • 如果内存中已经加载了具有相同模块名称的DLL,则系统仅判断重定向和 list ,然后再解析为加载的DLL,无论它位于哪个目录中.系统不会搜索DLL.
  • 如果某个DLL具有依赖项,系统将搜索依赖的DLL,就好像它们只加载了模块名一样.即使第一个DLL是通过指定完整路径加载的,也是如此.

唯一可行的解决方案是使外接程序严格依赖于另一个外接程序版本,并使用相同版本的CEF框架构建外接程序.如果另一个插件使用自定义构建的CEF框架,那么它可能无法工作.

Csharp相关问答推荐

我应该将新的httpReportMessage()包装在using声明中吗?

C#类主构造函数中的调试参数

使用客户端密钥为Fabric Rest API生成令牌

如何在Visual Studio代码中更改大括号模式{},用于C#语言

Unity 2D自顶向下弓旋转

在发布表单时绑定包含附加(嵌套)列表的对象列表的正确语法是什么

Blazor Foreach仅渲染最后一种 colored颜色

Blazor服务器端的身份验证角色

为基本审计设置Audit.EntityFramework.Core

C#普罗米修斯指标

是否有必要在ASP.NET Core中注册可传递依赖项?

用C#从XML内部元素中获取特定值

MudBlazor Textfield已禁用,但其验证工作正常

为什么ReadOnlySpan;T&>没有Slice(...)的重载接受Range实例的?

ASP.NET MVC数据批注验证组复选框

VS代码扩展无法在新版本扩展C#中运行从v2.10.28开始

序列化过程中的死循环

实体框架允许您具有筛选的属性吗?

如何在C#中反序列化Java持续时间?

反编译源代码时出现奇怪的字符