2010-02-21 15 views
2

我不想試圖解決我正在處理的個人痛苦,我想給它10000英尺的概述。我一邊學習.NET一邊學習.NET,並且我懷疑有一些東西顯而易見,因此我錯過了這裏。 我正在星期天加班加點,如果有人會在他們的五美分中折騰,我會非常感激。與.NET的Dllhell


這裏所說:

我們的支柱產品是過程控制系統。 有很多可能的方式來擴展/自定義系統。傳統上,我們將控制系統版本與受控制的過程工廠的特定配置分開,以便兩者可以分開維護。 (我稱之爲CS $)這是基礎版本。修復錯誤等。

C:\ Delivery Project \(我稱這個Proj $)這是受控系統的信息。

一點背景:

  • 我們的服務工程師希望能夠重新安裝或升級CS $文件夾無需定製數據丟失。
  • 交付項目傳統上由XCOPY部署。
  • 這兩者之間有一些dll引用,它在MFC中正常工作。
  • 在我們的實驗室機器上,通常會同時安裝多個版本。
  • 系統從駐留在交付項目中的.bat文件啓動,該項目設置環境並啓動。發射過程是環境變化劇烈的。

現在,我體驗到使用.NET時適應這種模型的一些困難。 當系統使用嵌入式.NET控件或顯示一個winform時,按需加載mscorlib,並且CS $ \ Run \ bin是應用程序的基本路徑。這給我帶來一些問題:

  • 在Proj $下部署的.NET程序集不在應用程序的基本路徑中。
  • 如果用戶重新安裝控制系統庫,將會刪除部署在CS $ \ Run \ bin下的.NET程序集。當然,我可以使部署成爲批量啓動的一部分。
  • .NET程序集路徑由駐留在Proj $文件夾結構中的文本配置提供。交付項目中的相對路徑很常見,但在開始訪問CS $時會出現問題,這可能會發生變化。
  • 在CS $ \ Run \ bin下部署的.NET程序集可能會有進一步的依賴關係。我可能在CS $ \ run \ bin \ ext1和CS $ \ run \ bin \下有兩個不同版本的Util1.dll。這導致CLR由於探測路徑順序而無法解析CS $ \ run \ bin \ ext1 \ util1.dll。
  • 我已經嘗試了AppDomain的分隔條件,但在CS $ \運行\ BIN \ EXT1 \ ext1.dll發現的類的實例可以在數百個號碼。我大量使用Singletons(靜態)來協調資源管理。

不用說,我使用了很多Reflector和Fuslogvw。還有更多我應該知道的工具嗎? 是否有可能檢查其中的CLR信息的運行進程?由於mscorlib是按需加載的,因此我有時會發現CLR的應用程序基礎很不好。這有時會阻止我的代碼被加載,所以我無法以編程方式訪問appdomain或輸出它來跟蹤。

有沒有什麼辦法可以控制探測路徑,從應用程序基路徑開始之前從調用程序集開始相對?

GAC中的混合模式程序集可以訪問CS $中的MFC資源嗎?

雖然我不擁有按需加載mscorlib的MFC代碼庫,但我的確有一種說法。那裏有什麼可以做的嗎?我將在加載mscorlib時輸出要跟蹤的關鍵信息(以及異常)。

文章,工具或某些方面的簡短說明我似乎缺少將不勝感激。

我感謝您抽出寶貴時間來閱讀這一點,並保持整個遺留疼痛清醒的頭腦,我在這裏描述:)

+0

男人,我可以感受到你的痛苦... – 2010-02-21 12:31:57

回答

1

如果NET的集探測邏輯不爲你工作了,你可以隨時使用IHostAssemblyManager和IHostAssemblyStore使用您自己的代碼擴展CLR主機。請參閱this blog post或閱讀this book以瞭解有關該選項的更多信息。

另一種選擇是重構應用程序以符合.Net的規則,而不是強制.Net按照您的規則來玩。也許如果你寫下功能需求而不是技術,你可能會發現你可以用另一種方式用.Net達到同樣的目標。如使用assembly version作爲程序集標識的一部分,shadow copy,publisher policies等。

+0

好東西。謝謝。 我仍然在.NET 1.1,它不允許我在常規探測嘗試失敗之前重寫。 我聽到你在重構問題上,但問題是,在我們的控制系統中,.NET只是許多可擴展點之一。項目和軟件的分離與我們的分佈和部署策略密切相關。我可能不得不使用啓動腳本來檢查並在必要時重新部署程序集(如果它們是作爲常規啓動的一部分從控制系統基礎文件夾中丟失的話)。 – Tormod 2010-02-21 17:04:27

1

如果您記錄瞭如何爲非託管程序集解決了這個問題,那將會很有幫助。指導Windows查找非託管DLL的選項受到很多限制。如果您要將.NET程序集安裝到GAC,那麼您的問題很容易解決,但這與您的部署策略不兼容。

Anyhoo,你幾乎可以肯定通過實現AppDomain.AssemblyResolve事件來解決你的問題。 CLR會在需要查找程序集時調用此函數,但無法自行找到它。您的代碼必須知道CS $和Proj $文件夾的位置才能使其正常工作。

+0

這是否允許我加載不位於應用程序基路徑下方或GAC中的相關程序集? – Tormod 2010-02-21 17:06:04

+0

是的,您可以在事件處理程序中使用Assembly.LoadFrom()。 – 2010-02-21 17:19:01