我們正在使用包裝器DLL以便自動更新我們的應用程序(我們的產品是DLL)。自動更新DLL
當應用程序關閉時,我們應該在哪裏釋放內部DLL?
(我們試圖做一個回調的DLLMain,但它似乎沒有工作,規格說,它不應該存在。)
謝謝
我們正在使用包裝器DLL以便自動更新我們的應用程序(我們的產品是DLL)。自動更新DLL
當應用程序關閉時,我們應該在哪裏釋放內部DLL?
(我們試圖做一個回調的DLLMain,但它似乎沒有工作,規格說,它不應該存在。)
謝謝
這是很模糊的,根本不清楚你的包裝是幹什麼的。通常,將一個DLL加載到進程中會對該文件進行鎖定。此鎖創建爲Windows將DLL映射到進程的虛擬內存地址空間的副作用,底層系統對象是內存映射文件。這將使任何嘗試覆蓋文件,而更新失敗。
您不應該在「應用程序正在關閉時」的情況下做任何特殊的事情,這也會讓您的DLL卸載並釋放對文件的鎖定。
更爲典型的問題是,您無法控制加載DLL的進程。直到該進程終止,您的更新才能完成。顯然,DLL不應該成爲強制終止主機進程的行爲,它不可能判斷將要做什麼樣的破壞。 A 可能包裝方法是爲每個將調用委託給實際DLL的導出函數擁有一個入口點。在GetProcAddress()中找到了哪些入口點,現在可以使用FreeLibrary()來卸載真正的DLL,以便更新它。當DLL不平凡時,這是非常痛苦和容易出錯的,您需要爲每個導出的函數使用函數指針聲明,並使用字符串而不是函數名稱。維護非常殘酷。
一種可能的替代方法是DLL上的鎖定在DLL的文件數據而不是目錄條目上的細節。它允許您在加載文件時將重命名爲。您的更新現在可以使用相同的名稱編寫更新的版本。程序下次啓動時,它將使用您的更新。然而,這不是完全可靠的,顯然程序將無法啓動,就像您應用更新一樣。考慮使用hard-link來避免該故障模式。
我假設您在檢查(並可能應用)內部DLL的可用更新後,使用LoadLibrary()從包裝DLL動態加載內部DLL。
如果您使用包裝器DLL與主機進程進行了合作,則可以導出在退出之前應由主機調用的Uninitialize()方法。在這個例程中,你可以調用FreeLibrary()並進行其他清理。
如果您沒有與主機進程的合作,那麼您通常運氣不好,無法正常清理。正如你所發現的,從DllMain中調用FreeLibrary()是不允許的,這是DLL通常關閉進程的唯一通知。
流程關閉期間泄漏DLL模塊句柄實際上不是一個大問題;系統正在跟蹤所有資源並自動清理它們。