簡體   English   中英

一個進程是否可以加載兩個同名但版本不同的dll?

[英]Is it possible for a process to load two dll with same name but different versions?

我兩天前在微軟社區發布了這個問題。 我得到了一些好主意,做了一些實驗,但還是失敗了。 如需更多幫助,我決定在此處發布此問題。 (原帖: 一個進程可以加載兩個不同版本的dll嗎?

我開發了一個word all-in 應用程序,它是一個可以被word 加載的dll和一些與word 兼容的應用程序(在這個問題中,我稱之為word-like 應用程序,它們使用相同的ooxml 標准)。 我的加載項使用 CEF .net 綁定cefglue (它又使用CEF (鉻嵌入框架))來呈現一些 Web 內容。 以下是我的加載項項目中的一些詳細信息。

此加載項的平台目標是Any CPU ,由這個類似單詞的應用程序加載。 啟動時,我通過調用Environment.Is64BitProcess檢查此加載項是在 32 位環境還是 64 位環境中加載。 之后,我為libcef.dll和其他 chromium 庫設置了適當的庫路徑,這取決於加載我的加載項 dll 的應用程序是 64 位還是 32 位。 例如,在 64 位字中,我的加載項加載 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 中運行良好,但不幸的是,這在那個類似單詞的應用程序中出現了一些問題。 原因如下:
這個詞類應用也有自己的cef庫來加載它的網頁內容(一些在線封面樣式、頁碼樣式等,可以在當前文檔中使用)。 如果我在這個詞類應用中打開了我的加載項,然后單擊一些觸發該詞類應用加載其網頁內容的按鈕,這個詞類應用就會崩潰。 為了分析原因,我應該給出一些事實:

庫我的加載項

myaddin.dll ( .net ) -> cefglue.dll( .net ) -> libcef.dll ( native dll , version 67) -> other chromium native dll

類庫應用加載

|-> myaddin.dll ( .net ) -> cefglue.dll ( .net ) -> libcef.dll ( native dll , version 67) -> other chromium native dll
|-> (加載自己的網頁內容時) -> ... -> libcef.dll ( native dll , version 87) -> other chromium native dll (在其安裝目錄中)

->代表loads|代表加載 dll 的獨立可能路徑)

我使用絕對路徑加載libcef.dll ,如果我先加載這個庫,那個類似單詞的應用程序不會加載它自己的libcef.dllLoadLibraryEx的內置規則?),然后它計划使用我的libcef.dll崩潰,畢竟它需要版本 87。如果類似單詞的應用程序首先加載libcef.dll ,我的加載項將不會加載版本 67 libcef.dll ,然后我得到version mismatch異常。

總而言之,我需要的是將同名但版本不同的libcef.dll與類似單詞的應用程序隔離開來,使其無法感知我的加載項加載的同名 dll。 一些想法? 謝謝。

這是不可能實現的,因為 libcef.dll 在依賴項中有其他 DLL,並且您無法控制它們的加載。 有關詳細信息,請參閱動態鏈接庫搜索順序 該頁面的重要部分是:

  • 如果內存中已經加載了具有相同模塊名稱的 DLL,則系統在解析到加載的 DLL 之前只檢查重定向和清單,無論它位於哪個目錄。系統不會搜索 DLL。
  • 如果 DLL 具有依賴關系,則系統會搜索依賴的 DLL,就好像它們僅加載了它們的模塊名稱一樣。 即使通過指定完整路徑加載第一個 DLL 也是如此。

唯一可行的解​​決方案是使您的外接程序嚴格依賴於另一個外接程序版本,並使用具有完全相同版本的 CEF 框架構建您的外接程序。 如果另一個插件正在使用自定義構建的 CEF 框架,它可能無法正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM