2010-05-25 48 views
2

問題:我在ASP.NET中使用嵌入式Firebird數據庫。ASP.NET從bin文件夾加載非託管dll

現在,Firebird有一個圍繞本地dll的.NET包裝。

問題是,在ASP.NET編譯和執行過程中,dll將陰影複製到臨時文件夾中。不幸的是,只有.NET dll,而不是本地dll。詳情請參閱http://msdn.microsoft.com/en-us/library/ms366723.aspx

現在,這使得必須將非託管dll置於system32目錄(或路徑環境變量中的任何其他目錄)。

現在,我想更改包裝/原生dll(opensource),因此如果它們只在bin文件夾中,它也會加載dll。

現在,我的問題是,我怎麼能在.NET中從絕對路徑加載非託管dll?
絕對路徑是在運行時確定的,而不是在編譯時...

回答

4

將本地dll嵌入到程序集中。

Application_Start(),檢查Environment.CurrentDirectoryAssembly.GetExecutingAssembly().Location或任何實際指向哪裏你想要的,該文件,如果不存在,通過Assembly.GetManifestResourceStream()流出來。

請注意,這可能會導致應用程序域回收,例如,重新啓動您的應用程序,但由於您剛啓動它,這是一個沒有問題。

不知道爲什麼你想要一個絕對路徑,尤其是對於一個非託管的dll。如果您只是將非託管dll與調用它的程序集放在同一目錄中,您將獲得更好的里程數,而且痛苦更輕。

+0

任何解決方案,不需要我將非託管dll放入路徑文件夾是受歡迎的。絕對路徑是我的想法,但嵌入一定會更好。 – 2010-05-25 18:11:43

2

我有類似的問題,但無論什麼原因,綁定/加載將失敗之前Application_Start()曾被調用。我的scenerio是我的web服務引用了我自己的其他項目(Called Common),後者又引用了供應商的託管C++ dll,後者又引用了非託管C++ dll。供應商的託管C++ dll未設置爲「延遲加載」供應商的非託管dll。這意味着ASP.Net/Fusion試圖加載託管的,它會馬上失敗。只需讓我的bin文件夾中的供應商管理的dll導致.Net嘗試加載它並失敗。

我的解決辦法是這樣的.....

  1. 創建刪除供應商的管理的DLL(非託管未被複制到我的斌,如預期)一後生成事件。這允許我的Web服務啓動,但如果我嘗試使用任何需要供應商的DLL的代碼,它將會失敗。
  2. 右鍵單擊Web服務,然後選擇Add-> Existing item。瀏覽到兩個供應商的DLL並選擇「添加爲鏈接」(點擊添加按鈕旁邊的向下箭頭)。
  3. 在新添加的供應商DLL的屬性選項卡中,使它們成爲嵌入式資源。
  4. 現在,在Application_Start中,我找到了我的公用庫在做的目錄Path.GetDirectoryName(Assembly.GetAssembly(typeof(ATypeInMyCommonLibrary)));使用它作爲我的輸出路徑,我將嵌入的dll取出Assembly.GetExecutingAssembly().GetManifestResourceStream並通過FileStream寫出來。

希望這會有所幫助!

+2

我最終稍微修改了這個方法。我最終有多個Web項目引用我的「Common」項目,所以我讓該項目嵌入了dll,並在我的類中添加了一個靜態構造函數(Common),實際上需要將vedor的DLL寫出來。這樣,我需要爲所有Web項目做的唯一事情就是發佈構建事件以刪除供應商的dll。 – 2010-12-17 13:57:53

+0

這個答案引導我朝着正確的方向發展,但對於我來說,即使加載器與程序集位於相同的臨時目錄中,也不會看到受管DLL。它從來沒有看過(用ProcMon驗證過)。相反,我爲AppDomain.CurrentDomain.AssemblyResolve添加了一個處理程序,並使用Assembly.LoadFile明確提供了該位置。 – jowo 2015-04-12 01:20:32

+0

您可以將「Copy Local」設置爲false以將其保留在bin目錄之外,而不是在複製之後將其刪除。 – jowo 2015-04-12 01:21:31