質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.04%

WinFormsでCefSharpを使用したときにDebug/Releaseモード以外で実行出来ない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 130

sera111

score 9

現在、WinFroms(C#)でアプリケーションを開発しているのですが、webサイトをアプリケーションに埋め込んで使用するのにCefSharpを使っています。
Debug/Releaseで実行すると問題なく動くのですが、bin/Releaseファイル内を別の場所へコピーして実行したりインストーラーを作成してインストールしてから実行すると下記のエラーが出てしまい実行出来ません。
実行するためにどのファイルを含めればいいか、どうすればいいかどなたかわかる方いませんでしょうか。

発生するエラー

System.BadImageFormatException: ファイルまたはアセンブリ 'CefSharp.WinForms, Version=75.1.143.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138'、またはその依存関係の 1 つが読み込めませんでした。間違ったフォーマットのプログラムを読み込もうとしました。

環境
・Windows10 64bit
・Visual Studio 2017
・.NET Framework 4.5.2

また、関係あるかは分かりませんがAnyCPUに対応するため(CefSharpのインストール後x64,x86ビルドも出来なかった)
https://www.valuestar.work/news/archives/27
を参考にしました。

追記
私の環境は64bitですので試しにx64フォルダ内をexeと同じ(root)フォルダにコピーして起動してみたらあっさり動きました。
ただこれでは解決になっていなくて、AnyCPUに対応できていないままですのでどうにかしてAnyCPUに対応させたいです。x86とx64でそれぞれ必要なファイルがフォルダごとに分かれているのですが、これをうまく認識してくれていないみたいで...。インストーラーに至ってはインストール時にそのフォルダを含めてくれない(認識されていないのが原因?)です。どなたか知恵をお貸し下さい...。

追記2
インストーラーはVisual Studio Installer Projectsを使用しています。
コードはほぼリンク先のままです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2019/11/08 07:52

    インストーラーの作成の詳細を質問に追記してください。
    こちらで問題が再現できるよう、詳細に書いてください。
    コードは問題の再現する「最小の」コードを「新しく」作って記載してください。

    キャンセル

  • dodox86

    2019/11/08 10:37

    > また、関係あるかは分かりませんがAnyCPUに対応するため(CefSharpのインストール後x64,x86ビルドも出来なかった)
    > https://www.valuestar.work/news/archives/27
    > を参考にしました。

    思いっきり関係ありそうですが、質問者さんの対応した手順がどうも不明瞭ですね。Qiitaのこちらの記事を読むと、CefSharpをAnyCPU対応するには、注意深い操作が必要なようです。
    https://qiita.com/yaju/items/97b61d0d8bc3f9ed044d

    > 私の環境は64bitですので試しにx64フォルダ内をexeと同じ(root)フォルダにコピーして起動してみたらあっさり動きました。

    とのことですが、インストーラーも含め、コードの修正、追加の過程で、どこか抜けてる手順がありそうです。エラー自体は、64ビットで動こうとしているところに32ビットのアセンブリを読み込もうとしたとか、その逆のパターンなのではないかと思います。

    キャンセル

  • sera111

    2019/11/08 10:57

    >質問者さんの対応した手順がどうも不明瞭ですね。
    リンク先ほぼそのままです。流れ的にはファイルをうまく読み込めなかった場合、64bitかどうかを判定してx86/x64フォルダ内で同名のファイルを探すという手順を踏んでいます。

    >64ビットで動こうとしているところに32ビットのアセンブリを読み込もうとしたとか、その逆のパターンなのではないかと思います。

    その通りでした。
    インストーラーがルートにx86用のファイルを作成していたため、そのファイルを認識してしまいエラーが出ていました。
    手動でコピーした際の問題は、そのゴミが残っていることに気付かなかったミスでした。
    インストーラーの設定でこのx86のファイルが削除出来なかったため、x86フォルダに手動で移動してあげることでとりあえずは解決出来たのですが、今度はインストーラーのビルド時にTargetPlatformをx86にするとビルドに失敗してしまう問題が起きてしまいました。TargetPlatformをx64にしてビルドしてインストールするととりあえず無事に動作させることが出来ましたが、このままだと32bitOSにインストーラーからインストール出来ない気がします。
    これについての対策はありますでしょうか。

    キャンセル

回答 1

checkベストアンサー

0

ご質問の状況を確認してみました。

Debug/Releaseで実行すると問題なく動くのですが、bin/Releaseファイル内を別の場所へコピーして実行したりインストーラーを作成してインストールしてから実行すると下記のエラーが出てしまい実行出来ません。

問題の原因としては既にある程度推察されているとおり、EXE実行ファイルから見たアセンブリDLLファイル群の配置場所です。

質問者さんが参考にされたサイト様の記事 CefSharpでAnyCPU対応に苦慮した話2 の
アセンブリを動的にロードする以下のコードは、実行ファイルの存在するディレクトリと実行時のプロセス(64ビットまたは32ビット)に応じて"x64/", "x86/"ディレクトリを切り替えているわけですから、

...※当該記事より抜粋の上、転載させていただいております。

string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + ".dll";
string archSpecificPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
                                       Environment.Is64BitProcess ? "x64" : "x86",
                                       assemblyName);

return File.Exists(archSpecificPath)
           ? Assembly.LoadFile(archSpecificPath)
           : null;

実行時のファイルの配置としては以下のようになっていなければならないはずです。(WinForms1.exe がCefSharpを組み込むEXE実行ファイルであるとします)

./
│  WinForms1.exe
│
├─x64/
│   CefSharp.Core.dll
│   CefSharp.dll
│   CefSharp.WinForms.dll
│   ...色々
│
└─x86/
     CefSharp.Core.dll
     CefSharp.dll
     CefSharp.WinForms.dll
     ...色々


この配置が守られていればメインのEXEがAnyCPUであろうと、x86、x64であろうと、正しく動作します。(NuGetでインストールした CefSharp.Common.75.1.143, CefSharp.WinForms.75.1.143 で確認済み)

Visual Studio Installerでファイルを配置するときも、このことを考慮して行えばインストーラーは作成できるかもしれません。下の画像は、x64とx86下にファイルを配置しようと試みた例です。ただし私の方では完成させておらず、未確認です。
イメージ説明

Visual Studio Installerはインストーラーを作成するには簡易的なツールであり(<と、私は思っています)、細かい制御は大変そうに思いました。私ならばVisual Studio Installerではなく、WiX(Windows Installer XML)を使ってしまうと思います。

尚、CefSharpを組み込んで実行すると自動的に「GPUCache」などのディレクトリやファイルが多数生成されました。インストーラーを作成するときは、これらの配置場所も考慮する必要があるかと思います。

個人的な意見ですが、Windowsが64ビット版であろうと32ビット(x86ビルド)の実行ファイルは動作するので、リリースする製品の形態によっては無理にAnyCPUで64ビット版と32ビット版を振り分けず、32ビット版のみでも良い気がします。他プログラムと連携する都合上、64ビット版Windowsであるときは64ビットプロセスで動作しないといけない、と言う要求があるのであれば仕方ありませんけれども。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/15 12:31

    返答が遅れてしまい申し訳ありません。
    上記でも回答しているように、インストーラーできちんとディレクトリを設定してビルドしてもインストーラー側の設定をtargetplatformをx86にしているとビルドに失敗してしまうという問題が解決できません。
    最終的にx86/x64で分けてインストーラーを作成するか、若しくはダミーでメインのexeを起動するだけのexeをインストーラーで指定してビルドすると出来るようになるかもしれないと思いました。(後者は試してないです。)

    > 私ならばVisual Studio Installerではなく、WiX(Windows Installer XML)を使ってしまうと思います。

    調べてみたいと思います。

    > Windowsが64ビット版であろうと32ビット(x86ビルド)の実行ファイルは動作するので、リリースする製品の形態によっては無理にAnyCPUで64ビット版と32ビット版を振り分けず、32ビット版のみでも良い気がします。

    もちろんその通りなのですが、CefSharpの前にWebBrowserを使っていた時に32bitだとメモリが足りずに落ちてしまうことがあったので、その関係で64bit環境ではx64で動かしたかったのです。ただ、その後しばらく使用してメモリ使用量を確認してみたら32bitでも足りそうなので32bit版のみでもいいかも知れません。

    ともあれ、インストーラーの設定や解決法等まとめて下さりありがとうございました。targetplatformの問題については質問内容自体とはそれている気がするので一度閉じさせていただこうと思います。

    キャンセル

  • 2019/11/15 13:26

    > インストーラーできちんとディレクトリを設定してビルドしてもインストーラー側の設定をtargetplatformをx86にしているとビルドに失敗してしまうという問題が解決できません。

    私も検証時に試しましたが、Visual Studio Installerでアセンブリを単なるファイルとして追加しようとしても、大きなお世話なことに勝手に依存関係を走査してエラーになるようですね。それらを制御するオプションも見当たらなかったので、どうやら「仕様」としてみるしかなさそうです。別案としてWiX云々を書きましたが、sara111さんが書かれているように、Visual Studio Installerでx86, x64用にそれぞれインストーラーを作成し、バッチファイルや自己解凍~実行ファイルに同梱して切り分ける方法がシンプルで良いかもしれません。環境変数PROCESSOR_ARCHITECTUREやPROCESSOR_ARCHITEW6432が切り分けのヒントになると思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる