I posted this question two days ago in Microsoft Community. I got some good ideas and did some experiments, but still failed. For more help, I decide to post this question here. (The original post: Is it possible for a process to load two dll with different versions?)
I developed a word all-in application which is a dll
that can be loaded by word and some word-compatible applications (in this question, I call it word-like app, they use the same ooxml standard). My add-in uses the CEF .net binding cefglue
(which in turn uses CEF
(chromium embedding framework)) to present some web contents. Here are some details in my add-in project.
This add-in's platform target is Any CPU
, loaded by this word-like app. When starting up, I check if this add-in is loaded in a 32-bit environment or 64-bit environment by calling Environment.Is64BitProcess
. After that, I set the appropriate library path for libcef.dll
and other chromium libraries which depends on the application that loads my add-in dll is 64-bit or 32-bit. For example, in 64-bit word, my add-in loads the 64-bit libcef.dll
. Some details using pseudocode:
// 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();
}
This works well in Microsoft Word, but unluckily, this arises some problems in that word-like app. Here is why:
That word-like app also has its own cef library to load its web contents (some online cover styles, page number styles, and so on, which are ready to be used in the current document). If I opened my add-in in this word-like app, then click some buttons that trigger the word-like app to load its web contents, this word-like app crashed. For analyzing the cause, I should give some facts:
Libraries my addin loads
myaddin.dll
(.net) -> cefglue.dll(.net) -> libcef.dll
(native dll, version 67) -> other chromium native dll
Libraries word-like app loads
|-> myaddin.dll
(.net) -> cefglue.dll
(.net) -> libcef.dll
(native dll, version 67) -> other chromium native dll
|-> (when loading its own web contents) -> ... -> libcef.dll
(native dll, version 87) -> other chromium native dll (in its installation directory)
(->
stands for loads
, |
stands for an independent possible path to load dlls)
I load libcef.dll
using absolute path, if I load this library first, that word-like app won't load its own libcef.dll
(the built-in rule of LoadLibraryEx
?), it plans to use my libcef.dll
then crash, after all it need the version 87. If the word-like app loads libcef.dll
first, my add-in won't load the version 67 libcef.dll
, then I get the version mismatch
exception.
All in all, what I need is to isolate the same name but different version libcef.dll
from that word-like app's, making it doesn't perceive the same name dlls loaded by my add-in. Some ideas? Thanks.
CodePudding user response:
This is impossible to implement, since libcef.dll has other DLLs in dependencies and you do not control their loading. See Dynamic-Link Library Search Order for details. The important parts of that page is:
- If a DLL with the same module name is already loaded in memory, the system checks only for redirection and a manifest before resolving to the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
- If a DLL has dependencies, the system searches for the dependent DLLs as if they were loaded with just their module names. This is true even if the first DLL was loaded by specifying a full path.
The only working solution is making your add-in strictly dependent on another add-in version and building your add-in with using CEF framework with the exact same version. It perhaps will not work if another plug-in is using a custom built CEF framework.