2010-03-30 51 views
2

兩個Delphi程序需要加載foo.dll,其中包含一些將客戶端身份驗證證書注入SOAP請求的代碼。 foo.dll駐留在c:\ fooapp \ foo.dll中,通常由c:\ fooapp \ foo.exe加載。這工作正常。其他程序需要相同的功能,但它駐留在c:\ program files \ unwantedstepchild \ sadapp.exe中。兩個AP加載DLL,此代碼:Delphi LoadLibrary無法找到DLL其他目錄 - 任何不錯的選擇?

FOOLib := LoadLibrary('foo.dll'); 
... 
If FOOLib <> 0 then 
begin 
    FOOProc := GetProcAddress(FOOLib , 'xInjectCert'); 
    FOOProc(myHttpRequest, Data, CertName); 
end; 

它foo.exe的偉大工程,爲DLL就在那裏。 sadapp.exe無法加載該庫,因此FOOLib爲0,其餘永遠不會被調用。因此,sadapp.exe程序默默無法注入證書,而當我們針對生產進行測試時,證書缺失,連接失敗。顯然,我們應該完全限定DLL的路徑。在沒有深入細節的情況下,測試方面直到最近才解決了這個問題,現在修復代碼基本爲時已晚,因爲這需要完整的迴歸測試,而且沒有時間。

由於我們自己畫到一個角落裏,我需要知道,如果有,我已經忽略了任何選項。儘管我們無法更改代碼(針對此版本),但我們可以調整安裝程序。我發現將c:\ fooapp放入路徑中工作。就像將foo.dll的第二個副本直接添加到c:\ program files \ unwantedstepchild中一樣。 c:\ fooapp \ foo.exe會一直運行,而sadapp.exe正在運行,所以我希望Windows可以找到它,但顯然不是。有沒有辦法告訴Windows,我真的想要同一個DLL?也許是一個清單或什麼?這是我期待的那種「神奇的子彈」。 我知道我可以:

  1. 修改Windows路徑,可能在安裝程序中。這很醜陋。
  2. 將DLL的第二個副本直接添加到unwantedstepchild文件夾中。也醜陋
  3. 延遲項目,同時我們編碼和測試一個適當的修復程序。不能接受的。
  4. 其他?

感謝您的任何指導,特別是與 「其他」。我明白這個問題並不一定是特定於德爾福的。謝謝!

+0

1和2是我可以接受的。你說這只是爲了這個版本。所以把它看作是一個臨時的解決方案。你可以在下一個版本中做到這一點。在我看來,你不需要浪費你的時間。 2可能更好,因爲您可以毫無問題地卸載它。 – Runner 2010-03-30 12:49:46

+0

你認爲你的選擇1和2是「醜陋的」。相反,這些都是股票標準技術,而且根本不難看。另一方面,你說「顯然,我們應該完全限定DLL的路徑」。 **絕對不是!**你在這裏建議的真***會是醜陋的***。不是每個人都熱衷於用你的'fooapp'文件夾污染他們的C:\文件夾結構。然而,通過硬編碼的方式,你不可能讓別人做任何事情。 _用戶應該能夠安裝到任何位置**或任何驅動器**並仍然有一個工作的應用程序。 – 2017-12-28 22:05:34

+1

您有第4個選項:將DLL安裝到Windows路徑上的共享文件夾中。窗口「系統文件夾」是一個候選人(但你可以使用和配置自己的文件夾,如果你選擇)。共享文件夾確實有一個小問題:這意味着所有應用程序都使用DLL的_same版本。並可能導致一個稱爲「DLL地獄」的問題(建議閱讀)。這通常通過在應用程序文件夾中放置特定版本的DLL來解決(即您的選項2)。所以自然我會建議選項2可能是最好的臨時解決方案;因爲無論如何它都會出現。 – 2017-12-28 22:14:35

回答

9

LoadLibrary MSDN文檔告訴你究竟在何處的Windows將搜索的DLL。您必須硬編碼DLL的路徑,將其放在與您的應用程序相同的文件夾中,或者將其放入LoadLibrary文檔的其中一個默認搜索位置。

+0

謝謝 - 這是一篇很好的文章,我顯然患有Delphi Myopia,因爲我忘記檢查MSDN。有趣的是,MSDN聲稱:「如果lpFileName不包含路徑並且有多個具有相同基本名稱和擴展名的已加載模塊,則該函數將返回首先加載的模塊的句柄。」我希望這會使我在這裏得救,但顯然這比它更多。即使foo.exe加載了foo.dll,SadApp.exe也無法利用它。 – 2010-03-30 13:07:53

+0

+1 Loadlibrary是我目前選擇的武器,因此我的建議會是。 – 2010-03-30 14:12:34

+0

由於我重新閱讀了MSDN文檔,問題已經解決了。關鍵是除了「從應用程序加載的目錄」之外還搜索「當前目錄」。好的,那爲什麼/什麼時候會有所不同呢?這是關鍵。通常,用戶從foo.exe的菜單中啓動SadApp。但也有一個可以獨立使用的圖標。那就是失敗的地方。當通過主應用程序的菜單「正常」啓動時,「當前目錄」爲c:\ fooapp,並找到並加載DLL。答對了!現在這只是一個程序/培訓問題。 – 2010-03-30 14:50:18

0

或者你可以簡單的編輯環境變量「路徑」,路徑放置到DLL在那裏。在這種情況下,將;c:\fooapp添加到路徑應該足夠。由於父級的環境更改會影響子級,因此您還可以創建加載程序應用程序,調整其環境變量,然後生成應用程序。

1

這不正是對提出的問題的解決方案,但它會幫助我,當我stumpled就這個問題:

您可以通過SetDllDirectory延長LoadLibrary的搜索路徑。

MSDN-Doku

搜索路徑可以使用SetDllDirectory會函數所改變。 建議使用此解決方案,而不是使用SetCurrentDirectory或 硬編碼DLL的完整路徑。

你會需要您的通話LoadLibrary(一個或多個)之前添加一行:

SetDllDirectory(PChar('c:\fooapp'));