🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

1回答

2854閲覧

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

sera111

総合スコア17

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

1クリップ

投稿2019/11/07 15:35

編集2019/11/08 01:59

現在、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を使用しています。
コードはほぼリンク先のままです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/11/07 22:33

インストーラーの作成に失敗しているだけでしょう。
sera111

2019/11/07 22:47

インストーラーだけでなく手動でファイルをコピーしてもダメなのですが...
Zuishin

2019/11/07 22:52

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

2019/11/08 01: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 01:57

>質問者さんの対応した手順がどうも不明瞭ですね。 リンク先ほぼそのままです。流れ的にはファイルをうまく読み込めなかった場合、64bitかどうかを判定してx86/x64フォルダ内で同名のファイルを探すという手順を踏んでいます。 >64ビットで動こうとしているところに32ビットのアセンブリを読み込もうとしたとか、その逆のパターンなのではないかと思います。 その通りでした。 インストーラーがルートにx86用のファイルを作成していたため、そのファイルを認識してしまいエラーが出ていました。 手動でコピーした際の問題は、そのゴミが残っていることに気付かなかったミスでした。 インストーラーの設定でこのx86のファイルが削除出来なかったため、x86フォルダに手動で移動してあげることでとりあえずは解決出来たのですが、今度はインストーラーのビルド時にTargetPlatformをx86にするとビルドに失敗してしまう問題が起きてしまいました。TargetPlatformをx64にしてビルドしてインストールするととりあえず無事に動作させることが出来ましたが、このままだと32bitOSにインストーラーからインストール出来ない気がします。 これについての対策はありますでしょうか。
guest

回答1

0

ベストアンサー

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

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

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

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

C#

1...※当該記事より抜粋の上、転載させていただいております。 2 3string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + ".dll"; 4string archSpecificPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, 5 Environment.Is64BitProcess ? "x64" : "x86", 6 assemblyName); 7 8return File.Exists(archSpecificPath) 9 ? Assembly.LoadFile(archSpecificPath) 10 : 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/09 04:49

dodox86

総合スコア9254

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sera111

2019/11/15 03: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の問題については質問内容自体とはそれている気がするので一度閉じさせていただこうと思います。
dodox86

2019/11/15 04:26

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問