Visual Studio 2022 の「Visual Studio Installer Projects(セットアッププロジェクト)」で MSI を作ろうとすると、参照している DLL や EXE が x64(AMD64)なのに、セットアップ側が x86 のままで「互換性がない」という警告やビルドエラーに悩まされることがあります。原因はほぼ一つで、直し方もシンプルです。この記事では、x64 で配布するために必要な設定と、再発しやすい落とし穴、SQLite などネイティブ DLL 依存がある場合の確認ポイントまでまとめます。
よく出る警告・エラーのパターン
症状としては、セットアッププロジェクトのビルド時に次のようなメッセージが出ます(文言は環境により多少異なります)。
SQLite.Interop.dll は 'AMD64' 用にビルドされています。
このセットアッププロジェクトのターゲットプラットフォーム 'x86' とは互換性がありません。
TT2025.exe / TT2025.dll は 'x64' 用にビルドされています。
ターゲットプラットフォーム 'x86' のプロジェクトでは使用できません。
つまり「中に入れたいファイルが 64bit なのに、インストーラー自身が 32bit 用として作られている」状態です。Visual Studio のプロジェクト構成をいくら AnyCPU や x64 にしても、セットアッププロジェクト側が x86 のままだと不一致が解消されません。
| 現象 | よくある原因 | 結論(最短ルート) |
|---|---|---|
| x64/AMD64 の DLL・EXE を追加すると警告が出る | セットアッププロジェクトの TargetPlatform が x86 のまま | セットアップ側の TargetPlatform を x64 に変更 |
| ビルドは通ったが、実行時に BadImageFormatException が出る | アプリが 32bit として起動している(AnyCPU + 32bit 優先など) | アプリ側も x64 に統一し、32bit 優先を外す |
| SQLite 関連だけが引っかかる | ネイティブ DLL(SQLite.Interop.dll)のビット数が混在 | x64 の Interop を同梱し、配置とコピー設定を見直す |
なぜセットアッププロジェクトだけ x86 のままになりやすいのか
Visual Studio Installer Projects(セットアッププロジェクト)は、アプリ側の「ソリューションプラットフォーム」や「プロジェクトの Platform target」とは別に、インストーラー(MSI)のプラットフォームを持っています。新規作成時に x86 が既定になっているケースが多く、次のような「見落とし」が起きます。
- アプリ側を x64 にしても、セットアッププロジェクトは自動で x64 にならない
- 構成マネージャーでソリューションのプラットフォームを x64 にしても、セットアップの TargetPlatform は別設定
- 結果として、x64 の EXE/DLL を入れようとして「互換性がない」と怒られる
x86 MSI と x64 MSI の違い
「インストーラーが 32bit か 64bit か」で、インストール先やレジストリのビューが変わります。単に“警告を消すための設定”ではなく、配布後の挙動に直結するため、ここを理解しておくと事故が減ります。
| 観点 | x86(32bit)インストーラー | x64(64bit)インストーラー | 実務上の影響 |
|---|---|---|---|
| 対応 OS | 32bit / 64bit の両方(基本) | 64bit OS のみ | 古い端末を切り捨てる判断が必要になる |
| 既定のインストール先 | Program Files (x86) | Program Files | ショートカットやパス指定の混乱を防げる |
| レジストリ | 32bit ビュー(Wow6432Node 側) | 64bit ビュー | 設定値の保存場所が変わるため、移行時は注意 |
| ネイティブ DLL 同梱 | x86 DLL が必要 | x64 DLL が必要 | 今回の警告はここが噛み合っていないサイン |
MSI は「どこに何を入れるか」を OS へ宣言する仕組みなので、パッケージのビット数が違うと、同じファイルを置いているつもりでも OS 側の扱いが変わることがあります。配布が x64 で確定しているなら、最初からインストーラーも x64 に統一するのが王道です。
解決策:セットアッププロジェクトの TargetPlatform を x64 に変更する
x64 で配布したいなら、まずはセットアッププロジェクト自体を x64 にします。これで「x64 ターゲットのファイルが x86 に互換性がない」という警告・エラーの大半は解消します。
操作手順
- ソリューション エクスプローラーで セットアッププロジェクト を選択する
- 右クリック → プロパティ を開く
- TargetPlatform(ターゲットプラットフォーム) を
x86からx64に変更する - 一度 クリーン してから 再ビルド する
| 設定箇所 | 項目名 | x64 配布時の推奨値 | ポイント |
|---|---|---|---|
| セットアッププロジェクトのプロパティ | TargetPlatform | x64 | ここが x86 のままだと、x64 ファイル追加時に警告/エラーになる |
| アプリ(.NET)プロジェクト | Platform target | x64(または AnyCPU でも x64 強制できる設計なら可) | ネイティブ DLL を読むなら、実行プロセスが x64 であることが重要 |
| アプリ(.NET)プロジェクト | Prefer 32-bit | オフ | AnyCPU でも 32bit 起動になり、ネイティブ x64 DLL と衝突しやすい |
ここでつまずきやすいポイント
- TargetPlatform を変えたのに警告が残る:セットアッププロジェクトに追加済みのファイル参照が古いことがあります。いったん対象ファイルを削除して追加し直す、またはクリーン → 再ビルドを試してください。
- ソリューションのプラットフォームを x64 にしただけ:セットアップ側の TargetPlatform は別設定なので、ここだけでは直りません。
- Release だけ直したつもり:デバッグで検証しているなら Debug 構成も x64 で揃えると混乱が減ります。
アプリ側も x64 に統一する:AnyCPU の落とし穴
セットアップを x64 にしても、アプリが 32bit として起動してしまうと、x64 のネイティブ DLL(SQLite.Interop.dll など)を読み込む段階で失敗します。典型例が BadImageFormatException です。これは「プロセスのビット数と DLL のビット数が合っていない」時に発生しやすい例外です。
構成マネージャーで x64 に揃える手順
- メニューの ビルド → 構成マネージャー を開く
- アプリのプロジェクト(TT2025 など)の プラットフォーム を
x64にする - Debug / Release の両方で同様に x64 になっているか確認する
- 必要なら「新規作成」で x64 を追加し、AnyCPU しか無い状態を避ける
プロジェクトのビルド設定で見直す項目
- Platform target:x64 を選ぶ
- Prefer 32-bit(32 ビットを優先):チェックが入っている場合は外す
- 出力先フォルダ:x86 の bin を参照していないか(セットアップが古いパスを拾っていないか)
特に AnyCPU は便利ですが、「ネイティブ DLL を同梱する」タイプのアプリでは、起動プロセスのビット数が実質的な制約になります。SQLite のように .NET からネイティブコンポーネントへ橋渡しする構成は、ビット数の統一を最優先にした方がトラブルが少なくなります。
セットアッププロジェクトに「何をどう追加するか」で結果が変わる
セットアッププロジェクトには、主に次の 2 通りの入れ方があります。どちらでも MSI は作れますが、参照する出力や更新タイミングが変わるため、混在すると「設定は直したのに古いファイルが入る」事故が起きがちです。
| 追加方法 | 特徴 | メリット | 注意点 |
|---|---|---|---|
| Project Output(プライマリ出力)を追加 | プロジェクトのビルド成果物を自動追従 | 依存 DLL を拾いやすい | 参照している構成(Debug/Release, x86/x64)を間違えると事故る |
| File を直接追加 | 指定したファイルをそのまま同梱 | 意図したファイルだけを確実に入れられる | ビルド後に手動で差し替えが必要になる場合がある |
おすすめは、まず Project Output を中心に構成し、どうしても自動で拾えないネイティブ DLL(SQLite.Interop.dll など)だけを File として補うやり方です。その上で「x64 の出力を拾っているか」を確認すると、再現性が高くなります。
SQLite.Interop.dll を含むネイティブ DLL 依存を安全に配布するコツ
SQLite 系でよくあるのは、管理コード(C# の DLL)自体は AnyCPU でも動く一方で、内部で読み込む SQLite.Interop.dll がネイティブ(x86 / x64 別物)である点です。ここが噛み合わないと、インストールはできても起動直後に落ちたり、特定機能だけが動かない現象になります。
確認すべきポイント
| チェック項目 | 見落とし例 | 対策 |
|---|---|---|
| 同梱している SQLite.Interop.dll が x64 か | x86 用を誤って混在させた | x64 版だけを同梱し、フォルダ構成も整理する |
| 実行ファイルと同じ場所に配置されるか | サブフォルダに入り、実行時に見つからない | アプリの EXE と同階層、または実行時の探索パスに置く |
| セットアップで「常にコピー」相当になっているか | ビルド出力からコピーされず旧 DLL が残る | セットアップ側で確実に含め、上書きされるようにする |
| CPU アーキテクチャ違いの DLL が残存していないか | 以前のテストで配置した DLL が残っている | 検証用 PC ではアンインストール後にフォルダを削除して再インストール |
“インストーラーが x64” であっても、配布物の中に x86 DLL が紛れ込むと意味がありません。逆に言うと、セットアップ側を x64 に揃えた上で、同梱物も x64 に統一できれば、SQLite 関連のトラブルは一気に減らせます。
64bit OS 以外には入れさせない(事故防止)
x64 インストーラーは基本的に 64bit OS でしか動かせませんが、配布ページから誤って 32bit 環境へ持ち込まれる可能性はゼロではありません。現場では「インストールしてから失敗する」より「最初に止める」方が親切です。
- 社内配布なら、対象 OS を 64bit に限定して周知する
- 不特定多数に配布するなら、インストーラー側に 64bit 必須の条件を入れる
セットアッププロジェクトの Launch Conditions を使える場合は、条件に VersionNT64 を指定して、64bit OS 以外ではメッセージを出して中断する運用が分かりやすいです(編集画面の名称は「起動条件」「起動条件エディター」などの表示になります)。
ビルド後に必ずやるべき検証
設定を変えたら、次の 3 点を確認して「本当に x64 配布物になっているか」をチェックします。ここを飛ばすと、環境依存の不具合として後から発覚しやすくなります。
インストーラー(MSI)の動作確認
- 64bit OS にインストールしたとき、既定のインストール先が Program Files 側になっているか(Program Files (x86) になっていないか)
- アンインストール → 再インストールでファイルが正しく更新されるか
- 管理者権限が必要な場所へ書き込む設計なら、インストール先や権限設計が妥当か
アプリ(EXE)のビット数確認
アプリが本当に 64bit として起動しているかは、タスクマネージャーやプロセス情報で確認できます。32bit で起動していると、ネイティブ x64 DLL は読み込めません。開発機で確認するときは、次のような「目視チェック」も有効です。
- タスクマネージャーの「詳細」タブで、32bit プロセスに付く表記(環境により列名が異なる)を確認する
- .NET Framework 系なら
corflags、ネイティブならdumpbin等でヘッダーを確認する(導入済みのツールがある場合)
同梱 DLL の整合性確認
- セットアップに含めた
SQLite.Interop.dllが、想定の場所に配置されているか - 同じフォルダに x86 版の DLL が残っていないか
- TT2025.dll など自作 DLL が、Release/x64 の出力を参照しているか
警告が消えない・挙動がおかしいときのチェックリスト
TargetPlatform を x64 に変えても、次のような理由で「まだ何かがおかしい」ことがあります。原因を切り分けるときは、上から順に潰していくと効率的です。
| チェック | 具体例 | 対処 |
|---|---|---|
| セットアップが参照している出力が古い | 以前の bin\x86\Release を拾っている | 「プライマリ出力」を追加し直す、出力パスを確認する |
| 構成が混在している | アプリは Debug/AnyCPU、セットアップは Release/x64 など | 検証用は構成を揃え、まず 1 組で安定させる |
| Prefer 32-bit が有効 | AnyCPU のまま実行すると 32bit 起動になる | Prefer 32-bit を外し、必要なら x64 固定にする |
| ネイティブ DLL の配置が不適切 | 実行時に見つからずロード失敗 | EXE と同階層に置く、探索パスを設計する |
| テスト環境に旧ファイルが残っている | 上書きされず旧 DLL が参照される | アンインストール後にフォルダごと削除し再インストール |
x86 と x64 の両方を配布したい場合の現実的な選択肢
「ユーザー環境が混在しているので 32bit/64bit 両方配りたい」という要件もあります。ただし、Visual Studio Installer Projects はシンプルさが強みである一方、1 つの MSI で柔軟に両アーキテクチャを切り替える用途は得意ではありません。実務的には次のいずれかが分かりやすいです。
| 方式 | 作りやすさ | ユーザーの迷い | 向いているケース |
|---|---|---|---|
| x86 用 MSI と x64 用 MSI を別々に作る | 高い | 中(選択が必要) | 配布ページで OS に応じて選ばせる運用ができる |
| ブートストラッパーで自動判定して導線を一本化する | 中 | 低い | インストーラーを 1 本化したい(やや設計コストあり) |
| WiX など別ツールへ移行する | 低い(学習が必要) | 低い | 条件分岐、依存関係、アップグレード制御など本格的にやりたい |
ただ、今回のように「最終的に x64 で配布したい」と決まっているなら、まずは x64 に統一してしまうのが最短です。32bit OS はすでに限定的で、サポート範囲を明確にするメリットもあります。
まとめ:x64 配布で迷ったら、まず TargetPlatform を見る
- セットアッププロジェクトはアプリ側とは別に TargetPlatform を持つ
- x64/AMD64 の EXE・DLL を入れたいなら、セットアップ側も x64 にする
- アプリ側も Debug/Release ともに x64 に揃え、AnyCPU の「32bit 優先」に注意する
- SQLite.Interop.dll のようなネイティブ DLL は、プロセスのビット数と同梱物の両面で整合性を取る
- 配布事故を避けるなら、64bit OS 必須の条件や周知もセットで考える
セットアッププロジェクトの設定は、普段あまり触らないため見落としがちです。しかし一度「インストーラーのビット数=同梱する実行ファイルのビット数」と腹落ちすると、原因特定と対処が一気に楽になります。x64 配布を前提に、構成を揃えた状態でビルド・インストール・起動まで一気通貫で確認してみてください。

コメント