我两天前在Microsoft社区发布了这个问题。我得到了一些好的想法和做了一些实验,但仍然失败了。为了更多帮助,我决定在这里发布这个问题。(原始文章: 一个进程是否可以加载两个具有不同版本的dll?)
我开发了一个word全能应用程序,它是一个dll
,可以被word和一些兼容word的应用程序加载(在这个问题中,我把它称为类似于word的应用程序,它们使用相同的ooxml标准)。我的插件使用CEF .net绑定cefglue
(它又使用CEF
(chromium嵌入框架))来呈现一些网页内容。下面是我插件项目中的一些细节。
这个插件的平台目标是Any CPU
,由这个类似于word的应用程序加载。启动时,我通过调用Environment.Is64BitProcess
检查这个插件是否在32位环境或64位环境下加载。之后,我根据加载我的插件dll的应用程序是64位还是32位来设置libcef.dll
和其他依赖于应用程序的chromium库的适当库路径。例如,在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的应用程序中会出现一些问题。原因如下:
那个类似于Word的应用程序也有自己的cef库来加载其网页内容(一些在线封面样式、页码样式等,这些都已准备好供当前文档使用)。如果我在这个类似于Word的应用程序中打开我的插件,然后点击一些按钮触发该应用程序加载其网页内容,那么这个类似于Word的应用程序就会崩溃。为了分析原因,我应该提供一些事实:
我的插件加载的库
myaddin.dll
(.net)-> cefglue.dll
(.net)-> libcef.dll
(native dll,版本67)-> 其他Chromium本机dll
类似于Word的应用程序加载的库
|->myaddin.dll
(.net)-> cefglue.dll
(.net)-> libcef.dll
(native dll,版本67)-> 其他Chromium本机dll
|->(加载自己的网页内容时)-> ...->libcef.dll
(native dll,版本87)-> 其他Chromium本机dll(在其安装目录中)
(->
代表加载
,|
代表一个独立的可能路径来加载dlls)
我使用绝对路径加载libcef.dll
,如果我首先加载这个库,那么那个类似于Word的应用程序就不会加载其自己的libcef.dll
(LoadLibraryEx
的内置规则?),它打算使用我的libcef. DLL
然后崩溃,毕竟它需要版本87。如果类似于Word的应用程序首先加载了libcef.dll
,那么我的插件将无法加载版本67的libcef.dll
,然后我会得到版本不匹配
异常。
总之,我需要隔离那个类似于Word的应用程序的相同名称但不同版本的libcef.dll
,使其不感知由我的插件加载的同名DLL。有一些想法吗?谢谢。
LoadLibrary
(而不是LoadLibraryEx
)来加载my.dll
,在my.dll
中加载libcef.dll
(如果我正确理解加载顺序,libcef.dll
将加载其他dll,如chrome_elf.dll
)。在my.dll
中,我使用GetProcAddress
来搜索cef函数,这些函数反过来又用于我的插件。my.dll
是我的插件和libcef.dll
之间的抽象层。 - Lucas