ダイナミック リンク ライブラリの検索順序

システムには、同じダイナミック リンク ライブラリ (DLL) の複数のバージョンを含めることができます。 アプリケーションは、完全なパスを指定するか、マニフェストなどの別のメカニズムを使用して、DLL の読み込み元の場所を制御できます。 これらのメソッドを使用しない場合、システムはこのトピックで説明するように読み込み時に DLL を検索します。

検索に影響を与える要因

次の要因は、システムが DLL を検索するかどうかに影響します。

  • 同じモジュール名を持つ DLL が既にメモリに読み込まれている場合、システムはリダイレクトとマニフェストのみをチェックしてから、読み込まれた DLL に解決します。どのディレクトリにあってもかまいません。 システムは DLL を検索しません。
  • アプリケーションが実行されているWindowsのバージョンの既知の DLL の一覧に DLL がある場合、システムは DLL を検索する代わりに、既知の DLL (および既知の DLL の依存 DLL がある場合) のコピーを使用します。 現在のシステム上の既知の DLL の一覧については、次のレジストリ キーを参照してください: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
  • DLL に依存関係がある場合、システムは依存 DLL を、モジュール名だけで読み込まれたかのように検索します。 これは、完全パスを指定して最初の DLL が読み込まれた場合でも当てはまります。

UWP アプリの検索順序

Windows 10用の UWP アプリ (または Windows 8.x 用のMicrosoft Store アプリ) が LoadPackagedLibrary 関数を呼び出してパッケージ化されたモジュールを読み込む場合、DLL はプロセスのパッケージ依存関係グラフに含まれている必要があります。 詳細については、「 LoadPackagedLibrary」を参照してください。 UWP アプリが他の方法でモジュールを読み込み、完全なパスを指定しない場合、システムはこのセクションで説明するように、読み込み時に DLL とその依存関係を検索します。

システムが DLL を検索する前に、次のチェックが行われます。

  • 同じモジュール名の DLL が既にメモリに読み込まれている場合、システムは読み込まれた DLL をどのディレクトリにあっても使用します。 システムは DLL を検索しません。
  • アプリケーションが実行されているWindowsのバージョンの既知の DLL の一覧に DLL がある場合、システムは既知の DLL (および既知の DLL の依存 DLL がある場合) のコピーを使用します。 システムは DLL を検索しません。 現在のシステム上の既知の DLL の一覧については、次のレジストリ キーを参照してください: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

システムがモジュールまたはその依存関係を検索する必要がある場合、依存関係が UWP アプリ コードでない場合でも、常に UWP アプリの検索順序が使用されます。

UWP アプリの標準検索順序

モジュールがまだ読み込まれていない場合、または既知の DLL の一覧に含まれている場合、システムは次の順序でこれらの場所を検索します。

  1. プロセスのパッケージ依存関係グラフ。 これは、アプリケーションのパッケージ と、アプリケーションのパッケージ マニフェストのセクションで<PackageDependency><Dependencies>指定された依存関係です。 依存関係は、マニフェストに表示される順序で検索されます。
  2. 呼び出し元のプロセスが読み込まれたディレクトリ。
  3. システム ディレクトリ (%SystemRoot%\system32)。

DLL に依存関係がある場合、システムは依存 DLL を、モジュール名だけで読み込まれたかのように検索します。 これは、完全パスを指定して最初の DLL が読み込まれた場合でも当てはまります。

UWP アプリの代替検索順序

LOAD_WITH_ALTERED_SEARCH_PATHを使用して LoadLibraryEx 関数を呼び出してモジュールが標準の検索順序を変更した場合、システムは呼び出し元プロセスのディレクトリではなく、指定したモジュールが読み込まれたディレクトリを検索します。 システムは、次の場所を次の順序で検索します。

  1. プロセスのパッケージ依存関係グラフ。 これは、アプリケーションのパッケージ と、アプリケーションのパッケージ マニフェストのセクションで<PackageDependency><Dependencies>指定された依存関係です。 依存関係は、マニフェストに表示される順序で検索されます。
  2. 指定したモジュールが読み込まれたディレクトリ。
  3. システム ディレクトリ (%SystemRoot%\system32)。

デスクトップ アプリケーションの検索順序

デスクトップ アプリケーションは、完全なパスを指定するか、DLL リダイレクトを使用するか、マニフェストを使用して、 DLL の読み込み元の場所を制御 できます。 これらのメソッドのいずれも使用しない場合は、このセクションで説明するように、読み込み時に DLL が検索されます。

システムが DLL を検索する前に、次のチェックが行われます。

  • 同じモジュール名の DLL が既にメモリに読み込まれている場合、システムは読み込まれた DLL をどのディレクトリにあっても使用します。 システムは DLL を検索しません。
  • アプリケーションが実行されているWindowsのバージョンの既知の DLL の一覧に DLL がある場合、システムは既知の DLL (および既知の DLL の依存 DLL がある場合) のコピーを使用します。 システムは DLL を検索しません。 現在のシステム上の既知の DLL の一覧については、次のレジストリ キーを参照してください: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

DLL に依存関係がある場合、システムは依存 DLL を、モジュール名だけで読み込まれたかのように検索します。 これは、完全パスを指定して最初の DLL が読み込まれた場合でも当てはまります。

重要

攻撃者が検索されるディレクトリの 1 つを制御すると、そのディレクトリに DLL の悪意のあるコピーが配置される可能性があります。 このような攻撃を防ぐ方法については、 ダイナミック リンク ライブラリのセキュリティに関するページを参照してください。

デスクトップ アプリケーションの標準検索順序

システムで使用される標準 DLL 検索順序は、安全な DLL 検索モードが有効か無効かによって異なります。 セーフ DLL 検索モードでは、後でユーザーの現在のディレクトリが検索順序に配置されます。

セーフ DLL 検索モードは既定で有効になっています。 この機能を無効にするには、 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode レジストリ値を作成し、0 に設定します。 SetDllDirectory 関数を呼び出すと、指定したディレクトリが検索パスにある間に SafeDllSearchMode が実質的に無効になり、このトピックの説明に従って検索順序が変更されます。

SafeDllSearchMode が有効になっている場合、検索順序は次のようになります。

  1. アプリケーションの読み込み元のディレクトリ。
  2. システム ディレクトリです。 GetSystemDirectory 関数を使用して、このディレクトリのパスを取得します。
  3. 16 ビット システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。
  4. Windows ディレクトリ。 GetWindowsDirectory 関数を使用して、このディレクトリのパスを取得します。
  5. 現在のフォルダー。
  6. PATH 環境変数に一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれないことに注意してください。 DLL 検索パスを計算するときに 、アプリ パス キーは使用されません。

SafeDllSearchMode が無効になっている場合、検索順序は次のようになります。

  1. アプリケーションの読み込み元のディレクトリ。
  2. 現在のフォルダー。
  3. システム ディレクトリです。 GetSystemDirectory 関数を使用して、このディレクトリのパスを取得します。
  4. 16 ビット システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。
  5. Windows ディレクトリ。 GetWindowsDirectory 関数を使用して、このディレクトリのパスを取得します。
  6. PATH 環境変数に一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれないことに注意してください。 DLL 検索パスを計算するときに 、アプリ パス キーは使用されません。

デスクトップ アプリケーションの代替検索順序

システムで使用される標準の検索順序は、LOAD_WITH_ALTERED_SEARCH_PATHを使用して LoadLibraryEx 関数を呼び出すことによって変更できます。 標準の検索順序は、 SetDllDirectory 関数を呼び出すことによっても変更できます。

Note

プロセスの標準的な検索順序も、現在のプロセスを開始する前に親プロセスで SetDllDirectory 関数を呼び出すことによって影響を受けます。

代替検索戦略を指定した場合、関連付けられているすべての実行可能モジュールが見つかるまで、その動作は続行されます。 システムが DLL 初期化ルーチンの処理を開始すると、システムは標準の検索戦略に戻ります。

LoadLibraryEx 関数は、呼び出しでLOAD_WITH_ALTERED_SEARCH_PATHを指定し、lpFileName パラメーターで絶対パスを指定する場合に、代替検索順序をサポートします。

LoadLibraryEx で指定された標準的な検索戦略と、LOAD_WITH_ALTERED_SEARCH_PATHで指定された代替検索戦略は、1 つの方法で異なります。標準検索は呼び出し元のアプリケーションのディレクトリから始まり、代替検索は LoadLibraryEx が読み込んでいる実行可能モジュールのディレクトリから開始されます。

SafeDllSearchMode が有効になっている場合、代替検索順序は次のようになります。

  1. lpFileName で指定されたディレクトリ。
  2. システム ディレクトリです。 GetSystemDirectory 関数を使用して、このディレクトリのパスを取得します。
  3. 16 ビット システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。
  4. Windows ディレクトリ。 GetWindowsDirectory 関数を使用して、このディレクトリのパスを取得します。
  5. 現在のフォルダー。
  6. PATH 環境変数に一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれないことに注意してください。 DLL 検索パスを計算する場合、 アプリ パス キーは使用されません。

SafeDllSearchMode が無効になっている場合、代替検索順序は次のようになります。

  1. lpFileName で指定されたディレクトリ。
  2. 現在のフォルダー。
  3. システム ディレクトリです。 GetSystemDirectory 関数を使用して、このディレクトリのパスを取得します。
  4. 16 ビット システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。
  5. Windows ディレクトリ。 GetWindowsDirectory 関数を使用して、このディレクトリのパスを取得します。
  6. PATH 環境変数に一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれないことに注意してください。 DLL 検索パスを計算する場合、 アプリ パス キーは使用されません。

lpPathName パラメーターでパスが指定されている場合、SetDllDirectory 関数は代替検索順序をサポートします。 代替検索順序は次のとおりです。

  1. アプリケーションの読み込み元のディレクトリ。
  2. SetDllDirectorylpPathName パラメーターで指定されたディレクトリ。
  3. システム ディレクトリです。 GetSystemDirectory 関数を使用して、このディレクトリのパスを取得します。 このディレクトリの名前は System32 です。
  4. 16 ビット システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。 このディレクトリの名前は System です。
  5. Windows ディレクトリ。 GetWindowsDirectory 関数を使用して、このディレクトリのパスを取得します。
  6. PATH 環境変数に一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれないことに注意してください。 DLL 検索パスを計算する場合、 アプリ パス キーは使用されません。

lpPathName パラメーターが空の文字列の場合、呼び出しは現在のディレクトリを検索順序から削除します。

SetDllDirectory は 、指定されたディレクトリが検索パスにある間、安全な DLL 検索モードを効果的に無効にします。 SafeDllSearchMode レジストリ値に基づいて安全な DLL 検索モードを復元し、現在のディレクトリを検索順序に復元するには、lpPathName を NULL として使用して SetDllDirectory を呼び出します。

LOAD_LIBRARY_SEARCH フラグを使用した検索順序

アプリケーションでは、LoadLibraryEx 関数で 1 つ以上のLOAD_LIBRARY_SEARCH フラグを使用して、検索順序を指定できます。 アプリケーションでは、SetDefaultDllDirectories 関数で LOAD_LIBRARY_SEARCH フラグを使用して、プロセスの DLL 検索順序を確立することもできます。 アプリケーションでは、 AddDllDirectory 関数または SetDllDirectory 関数を使用して、プロセス DLL 検索順序の追加ディレクトリを指定できます。

検索されるディレクトリは、 SetDefaultDllDirectories または LoadLibraryEx で指定されたフラグによって異なります。 複数のフラグを使用する場合、対応するディレクトリは次の順序で検索されます。

  1. DLL (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) を含むディレクトリ。 このディレクトリは、読み込まれる DLL の依存関係のみを検索します。
  2. アプリケーション ディレクトリ (LOAD_LIBRARY_SEARCH_APPLICATION_DIR)。
  3. AddDllDirectory 関数 (LOAD_LIBRARY_SEARCH_USER_DIRS) または SetDllDirectory 関数を使用して明示的に追加されたパス。 複数のパスが追加されている場合、パスの検索順序は指定されません。
  4. システム ディレクトリ (LOAD_LIBRARY_SEARCH_SYSTEM32)。

アプリケーションが LOAD_LIBRARY_SEARCH フラグを指定して LoadLibraryEx を呼び出したり、プロセスの DLL 検索順序を確立したりしない場合、システムは標準の検索順序または代替検索順序を使用して DLL を検索します。

AddDllDirectory

アプリケーションの登録

ダイナミック リンク ライブラリのリダイレクト

ダイナミック リンク ライブラリのセキュリティ

Loadlibrary

LoadLibraryEx

LoadPackagedLibrary

SetDefaultDllDirectories

SetDllDirectory

サイド バイ サイド コンポーネント