Visual Studio 2022 .net7 C#(Csharp)で動作確認。
自作のアプリ開発をしていてどーも「単一のexeファイル出力(make single exe file)」が上手くいかず、半年以上詰んでました。ひつじです。
作ったはいいものの、ファイルサイズは肥大化(設定次第で74MB~240MBにまで変化)、そもそも ダブルクリックしても起動しない という、途方に暮れてました。
質問してみてもやり方知ってる人も居ないんですよねぇ。。。(遠い目)
そこで、テストプロジェクトを作成し、実験してみました。
ソリューションエクスプローラーの右クリックメニューから「発行」です
実際、単純なテストプロジェクトであれば難なくこれは行えることが分かりました。
出力場所を変えようと、TargetRuntimeや構成のCPUを変えるようと問題なく単一のexeとして出力出来ます。
参考になったLink
何が問題だったのか?
ここで、テストプロジェクトに背景画像を設定してみました。
画像のビルドアクションを「コンテンツ」にしてビルドすると、 単一のexeを作成しても動作しない事が分かりました。
正解は 対象の画像のビルドアクションを「リソース」に替えることです。ビルドに成功したら発行すれば良いという非常に単純な事でした。
切り替え後に「ソリューションのクリーン」を行う必要があったことを付け加えておきます。
※画像は頂きもので、このキャラクターを使用したアプリ開発を行っています。
出力されるファイルサイズが大幅に削減され、フォイル数も7個程度まで減らす事が出来ました。
自作のアプリではバイナリのサイズは24.2MBでした。元のサイズは251kbですが、十分許容範囲だと思われます。
この件の教訓。 他人はあまり役に立たない
いいたか無いですがこの件のために半端じゃないぐらい色々試しています....
dllファイルも内部に取り込める
これを実現するために数多くの記事を参照しましたが、全てが無駄でした そのような事をせずともdllは単一のexeとして格納されるようです。上手く行きさえすれば。
参考までに設定内容も付記しておきます。
デバッグシンボル : PDBファイル、現在のプラットフォーム
※変更して発行しなおしても問題なかったので多分関係ない
アセンブリに署名する:チェック
試してみて全くの無駄だったもの
ChatGPTの回答。
以下はプローブを使用するという方法です
App.Config 作成 →
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="dll" />
</assemblyBinding>
</runtime>
改めて検証しましたが、
1.Visual Studio 2022では”アプリ名”+exe.Configが作成されない
→無効になっている?
2.”アプリ名”+dll.Config なら作成される
3.App.Configを作成して追加したり、ドラッグ&ドロップで当該のファイルを導入したりしてみた
結局、は動作していないようにしか見えず、defaultのprobe検索アルゴリズムが動作している模様。
→あるいは記述が間違っている?
→CodeBase要素を先に検索するとのこと
4.プロジェクト内にあるApp.Configや”アプリ名”+dll.Configを ”アプリ名”+exe.Configにリネームしてみた
→意味がないと判断せざる負えなかった
いずれにせよ、Visual Studio 2022では通用しない方法だと判断せざる負えず断念中。当該ファイル群ののビルドアクションも弄ってみましたが、意味は無かったです。
App.Xanl.csへの
namespace HaruaConvert
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// string exeDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
// string dllDir = Path.Combine(exeDir, "dll");
// try
// {
// string[] fileList = Directory.GetFiles(dllDir);
// foreach (string file in fileList)
// {
// if (Path.GetExtension(file).Equals(".dll", StringComparison.OrdinalIgnoreCase))
// {
// Assembly.LoadFrom(file);
// }
// }
// }
// catch (Exception ex)
// {
// // 例外処理: ファイルの読み込みやアセンブリのロードに関するエラーが発生した場合の処理
// Console.WriteLine($"Error loading assemblies: {ex.Message}");
// }
//}
}
}
}
一部をChatGPTに手直ししてもらったもの。
なんていうかいかにも意味ありげに見えるのが曲者なんですよねぇ
この件に関しての追加調査
.Net5から doesn't work in .Net 5.0 と報告されている。
必要ならCromeでも使って翻訳して読んでみて欲しい。
一応Web魚拓を取得しておいた。
要するに.Net 5.0以降、<probing privatePathは使えない。らしい。
この事から、2020/11/11(.net5.0 のリリース日)以前の単一ファイルを出力するTips系の記事はVisual Studio2022において全く使用できないと結論付ける事が出来ます。了