アプリケーションの自動更新を可能にするために、ラッパー DLL を使用しています (当社の製品は DLL です)。
アプリケーションを閉じるときに内部 DLL を解放する場所は?
(DLLMain コールバックで実行しようとしましたが、機能していないようで、仕様では存在しないように指定されています。)
ありがとうございました
アプリケーションの自動更新を可能にするために、ラッパー DLL を使用しています (当社の製品は DLL です)。
アプリケーションを閉じるときに内部 DLL を解放する場所は?
(DLLMain コールバックで実行しようとしましたが、機能していないようで、仕様では存在しないように指定されています。)
ありがとうございました
これは非常にあいまいです。ラッパーが何をするかはまったくわかりません。一般に、DLL をプロセスにロードすると、ファイルがロックされます。このロックは、Windows が DLL をプロセスの仮想メモリ アドレス空間にマッピングすることの副作用として作成されます。基になるシステム オブジェクトは、メモリ マップ ファイルです。これにより、更新中にファイルを上書きしようとすると失敗します。
「アプリケーションが閉じているとき」の場合、特別なことをする必要はありません。これにより、DLL もアンロードされ、ファイルのロックが解除されます。
より一般的な問題は、DLL をロードするプロセスをまったく制御できないことです。そのプロセスが終了するまで、更新は完了できません。そして明らかに、DLL は、ホスト プロセスを強制的に終了させるビジネスに関与すべきではありません。DLL は、それがどのような種類の損害を与えるかを判断することはできません。可能なラッパーアプローチは、実際の DLL への呼び出しをデリゲートするすべてのエクスポートされた関数のエントリポイントを持つものです。GetProcAddress() でエントリポイントが見つかったので、FreeLibrary() を使用して実際の DLL をアンロードして更新できるようになりました。DLL が自明でない場合、これは非常に苦痛でエラーが発生しやすくなります。エクスポートされた関数ごとに関数ポインター宣言が必要であり、関数名の代わりに文字列を使用します。メンテナンスはかなり厳しいです。
考えられる別のアプローチの 1 つは、DLL のロックが、ディレクトリ エントリではなく、DLL のファイル データにあるという詳細です。これにより、ロード中にファイルの名前を変更できます。これで、更新により、更新されたバージョンを同じ名前で書き込むことができます。プログラムの次回起動時に、更新プログラムが使用されます。ただし、これは完全に信頼できるものではありません。明らかに、更新を適用しているときにプログラムが起動しません。その障害モードを回避するには、ハードリンクを使用することを検討してください。
内部 DLL の利用可能な更新プログラムをチェックした後 (および潜在的に適用した後)、LoadLibrary() を使用してラッパー DLL から内部 DLL を動的にロードしていると仮定します。
ラッパー DLL を使用するホスト プロセスの協力がある場合は、終了する前にホストによって呼び出される Uninitialize() メソッドをエクスポートできます。このルーチンでは、FreeLibrary() を呼び出して、その他のクリーンアップを行うことができます。
ホスト プロセスの協力が得られない場合、通常、適切にクリーンアップすることはできません。お気づきのように、DllMain 内から FreeLibrary() を呼び出すことは許可されていません。これは、DLL が通常プロセスがシャットダウンしているという通知を受け取る唯一の通知です。
プロセスのシャットダウン中に DLL モジュール ハンドルをリークすることは、実際には大きな問題ではありません。システムはすべてのリソースを追跡しており、それらを自動的にクリーンアップします。