| この記事の要点 |
|
結論: exe と同じフォルダに置く
開発環境では動くのに、本番環境に配置すると「DLL が見つからない」エラーになる、というのはよくあるトラブルです。自作 DLL(A.dll)がさらに別の DLL(B.dll)を参照している場合、B.dll はアプリケーションの実行ファイル(.exe)と同じディレクトリに置くのが最も確実で、推奨される方法です。
C:\MyApp\
MyApp.exe ← 起動する実行ファイル
A.dll ← MyApp.exe が参照する DLL
B.dll ← A.dll が参照する DLL(ここに置く)
MyApp.exe.config
Visual Studio でビルドすると、参照設定で「ローカルにコピー(Copy Local)」が有効な DLL は自動で出力フォルダ(bin\Release など)にコピーされます。本番には出力フォルダの中身を丸ごと配置するのが基本です。
最大の落とし穴: 参照元 DLL のフォルダは探されない
「A.dll が使うのだから、A.dll と同じフォルダに B.dll を置けばよい」と考えがちですが、Windows も .NET も、依存 DLL の検索の基準は参照元の DLL の場所ではなく、プロセス(exe)の場所です。
例えば A.dll と B.dll を C:\Shared\Lib に置き、C:\MyApp\MyApp.exe から A.dll を読み込んだ場合、B.dll は C:\MyApp などから探され、C:\Shared\Lib は探されません。プラグイン形式で DLL を別フォルダから読み込む設計のときに特に起こりやすい問題です。
ネイティブ DLL(C/C++ など)の検索順序
C/C++ で作られたネイティブ DLL や、C# から P/Invoke(DllImport)で呼び出す DLL は、Windows のローダーが次の順で検索します(既定の安全な DLL 検索モードが有効な場合)。
- アプリケーションの実行ファイルがあるディレクトリ
- システムディレクトリ(
C:\Windows\System32) - 16 ビットのシステムディレクトリ(
C:\Windows\System) - Windows ディレクトリ(
C:\Windows) - カレントディレクトリ
- 環境変数 PATH に含まれるディレクトリ
この前に、すでにメモリに読み込まれている DLL や、Windows が管理する既知の DLL(KnownDLLs)が優先されます。
各配置場所の比較
| 置き場所 | 評価 | 理由 |
|---|---|---|
| exe と同じフォルダ | 推奨 | 最初に検索される。アプリごとに独立し、他のアプリへ影響しない |
| System32 / SysWOW64 | 非推奨 | 管理者権限が必要。システム全体に影響し、同名 DLL の上書き事故(DLL 地獄)の原因になる |
| PATH に含まれるフォルダ | 条件付き | 複数アプリで共有できるが、PATH の順番や他ソフトの同名 DLL で読み込まれる DLL が変わりうる |
| アプリ固有のフォルダ | 設計次第 | アプリ側が SetDllDirectory や AddDllDirectory で検索先を追加している場合のみ有効 |
64 ビット版 Windows では、System32 が 64 ビット用、SysWOW64 が 32 ビット用です。名前と中身が直感と逆なので注意してください。
.NET アセンブリ(C# の DLL)の場合
C# などで作ったマネージド DLL(アセンブリ)は、ネイティブ DLL とは別の仕組みで探されます。
- .NET Framework: アプリケーションベース(exe のフォルダ)を探し、厳密名付きのものはグローバルアセンブリキャッシュ(GAC)も参照します
- .NET(.NET Core / .NET 5 以降): ビルド時に生成される
アプリ名.deps.jsonに依存関係が記録され、通常は exe と同じフォルダから読み込まれます。dotnet publishの出力フォルダを丸ごと配置すれば必要な DLL がそろいます
サブフォルダに DLL をまとめたい場合(.NET Framework)
exe のフォルダを整理するため lib フォルダに DLL を入れたい場合は、app.config(実行時は MyApp.exe.config)で検索先を追加します。指定できるのはアプリケーションベース配下のサブフォルダだけです。
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib;plugins" />
</assemblyBinding>
</runtime>
</configuration>
よくあるエラーと原因
| エラー | 主な原因 |
|---|---|
| FileNotFoundException: ファイルまたはアセンブリ '…'、またはその依存関係の 1 つが読み込めませんでした | .NET の DLL か、その DLL が依存する DLL が exe のフォルダにない |
| DllNotFoundException | P/Invoke で呼ぶネイティブ DLL、またはその依存 DLL が見つからない |
| BadImageFormatException | 32 ビットと 64 ビットの不一致(x86 用 DLL を 64 ビットプロセスで読む等) |
| VCRUNTIME140.dll が見つからない | 本番機に Visual C++ 再頒布可能パッケージが入っていない |
「その依存関係の 1 つ」という文言のとおり、エラーに表示された DLL 自体ではなく、その先の依存 DLL が見つからないケースが多くあります。
どこを探したか確認する方法
- 依存関係を一覧する: Visual Studio の開発者コマンドプロンプトで
dumpbin /dependents A.dllを実行すると、A.dll が必要とするネイティブ DLL の一覧が出ます - 読み込みの試行を記録する: Sysinternals の Process Monitor で対象プロセスを絞り込み、「NAME NOT FOUND」になっている DLL のパスを確認します
- .NET Framework のバインド失敗: アセンブリ バインド ログ ビューアー(fuslogvw.exe)で、どのフォルダを探して失敗したかが分かります
- 本番機と開発機で、exe のフォルダの中身(DLL の数・バージョン・ビット数)を比較します
関連
- DLL ファイル(.dll)とは | Windows 動的リンクライブラリの仕組み・LoadLibrary・DLL Hijacking 対策
- C#・Visual Studioのよくあるエラーと対処まとめ
- C# 入門 — .NET エコシステムと現代の C# 言語
- EXE / DLL / MSI / DMG / DEB / RPM / APK など実行・パッケージ形式総覧
子ページはありません
- ショートカットキー
- dllを参照する方法
- エラー一覧
- 本番環境のdll内で参照しているdllファイルの置き場所
- フォームのタブ切り替え順序を変更する方法
- .suoファイルとは
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09