別のexeを、自分のアプリ(exe)に取り込んで、好きな時に吐き出して実行する

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

自分が作ったプログラムのexeと同じ階層に、あらかじめ指定のファイルを配置しておきたい場合に、 下図のように、ソリューションエクスプローラーにファイルを追加して、そのプロパティで「出力ディレクトリにコピー」を「常にコピーする」にしておくと、ビルドしたときに、自動的に、exeと同じ階層に、そのファイルがコピーされてくれる。

この画像では、例としてpngファイルにしたが、 今回は、pngではなく、別のexeを抱え込んで、かつあらかじめ配置はせずに、

  • アプリ(exe)にその別のexeファイルを抱え込んでおいて、
  • 通常はその別のexeは見えないようにしておいて、
  • アプリの任意のタイミングでそのexeファイルを具現化?して、
  • そのexeファイルを実行する

ようなことをしたい。

前提

  • .NET6
  • コンソールアプリ使用

やり方

VisualStudioの「リソース」の機能を使った。

リソースを追加する

まず、プロジェクトを右クリックし、[追加] > [新しい項目]を押す。

出てきた選択画面で、「リソースファイル」を選ぶ。

そうすると、プロジェクトの下に「Resource1.resx」ができる。

ソリューションエクスプローラーの中の「Resource1.resx」をダブルクリックすると、リソースの画面が開く。 ここまでは、以前調べたローカライズのためのreswと同じやり方。

下記の画面が開いたら、アクセス修飾子「public」にする。

次に、「リソースの追加」を押し、「既存のファイルの追加」を押す。

今回は、「別のexe」として、ファイル比較でよく使うDF.exeでやってみるので、出てきた選択画面で、DF.exeを選ぶ。

そうすると、自動で「Resources」フォルダができて、その中に今選択したファイルが入る。

resx画面の方で追加したファイルをクリックして選択すると、下図のようなプロパティが表示される。
Typeが「System.Byte[]」になっている。

Resource1.Designer.csを開くと、追加したリソースがこんな感じで定義されている。
byte[]のリソースになっている。

これで、リソースの追加は終わり。

追加したリソースをコードから呼ぶ

下記のようなコードを書いた。

using System.Diagnostics;

namespace BinTorikomi
{
    internal class Program
    {
        private static string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

        static void Main(string[] args)
        {
            // リソースを取ってくる
            var exe = Resource1.DF;

            // 出力先のパスを決める
            var outputExePath = Path.Combine(desktopPath, "DF2.exe");

            // リソースを書き出す
            using (var fs = new FileStream(outputExePath, FileMode.Create))
            using (var sw = new BinaryWriter(fs))
            {
                sw.Write(exe);
            }

            // 書き出したファイルを実行する
            Process.Start(outputExePath);

            Console.ReadLine();
        }
    }
}

まず、これで、元のDF.exeを全部バイナリにしたバイト列を取れる。(型はbyte[]

var exe = Resource1.DF;

それを取れたら、あとは、DF.exeを復元するには、ただそのバイト列をファイルとして書き出せばよい。 (書き出し方の参考→ファイルに文字列/バイナリデータを読み書きする

で、書き出したら、Process.Startでそのファイルを実行する。

これで出来上がり。

参考

ファイルに文字列/バイナリデータを読み書きする

https://qiita.com/tera1707/items/65025aca202ef0535fa5