web-dev-qa-db-ja.com

C#プログラム内への外部実行可能ファイルの埋め込み

C#Windows Formsアプリケーション内に外部実行可能ファイルを埋め込むにはどうすればよいですか?

編集:それは私がプログラムで使用する出力値を読み取る外部の無料コンソールアプリケーション(C++で作成)であるため、埋め込む必要があります。それを埋め込むことは、ニースでより専門的です。

2番目の理由は、.NETアプリケーション内にFlashプロジェクターファイルを埋め込む必要があることです。

36
Josh

以下は、これを大まかに達成するサンプルコードです。また、埋め込まれるプログラムのライセンスがこの種の使用を許可していることを確認してください。

// extracts [resource] into the the file specified by [path]
void ExtractResource( string resource, string path )
{
    Stream stream = GetType().Assembly.GetManifestResourceStream( resource );
    byte[] bytes = new byte[(int)stream.Length];
    stream.Read( bytes, 0, bytes.Length );
    File.WriteAllBytes( path, bytes );
}

string exePath = "c:\temp\embedded.exe";
ExtractResource( "myProj.embedded.exe", exePath );
// run the exe...
File.Delete( exePath );

唯一のトリッキーな部分は、ExtractResourceの最初の引数に正しい値を取得することです。 「namespace.name」という形式にする必要があります。名前空間はプロジェクトのデフォルトの名前空間です(プロジェクト|プロパティ|アプリケーション|デフォルトの名前空間の下にあります)。 2番目の部分はファイルの名前であり、プロジェクトに含める必要があります(ビルドオプションを[埋め込みリソース]に設定してください)。ファイルをディレクトリの下に置いた場合、例えばリソース、その名前はリソース名の一部になります(例:「myProj.Resources.Embedded.exe」)。問題がある場合は、Reflectorでコンパイル済みのバイナリを開いて、Resourcesフォルダーを確認してください。ここにリストされている名前は、GetManifestResourceStreamに渡す名前です。

21
Charlie

ウィルが言った :から始まる最も簡単な方法

  1. Resources.resxを使用して.exeを追加します
  2. これをコーディング:

    string path = Path.Combine(Path.GetTempPath(), "tempfile.exe");  
    File.WriteAllBytes(path, MyNamespace.Properties.Resources.MyExecutable);
    Process.Start(path);
    
59
dav_i

それをプロジェクトに追加し、ビルドオプションを「Embedded Resource」に設定するだけです

14
scottm

これはおそらく最も簡単です:

byte[] exeBytes = Properties.Resources.myApp;
string exeToRun = Path.Combine(Path.GetTempPath(), "myApp.exe");

using (FileStream exeFile = new FileStream(exeToRun, FileMode.CreateNew))
    exeFile.Write(exeBytes, 0, exeBytes.Length);

Process.Start(exeToRun);
7
nawfal

実行可能ファイルはマネージアセンブリですか?その場合は、 ILMerge を使用して、そのアセンブリを自分のアセンブリとマージできます。

4
Andrew Hare
  1. VSプロジェクトにファイルを追加
  2. 「埋め込みリソース」としてマーク->ファイルのプロパティ
  3. 名前を使用して解決:[アセンブリ名]。[埋め込みリソースの名前]「MyFunkyNTServcice.SelfDelete.bat」など

コードにリソースバグがあります(ファイルハンドルが解放されません!)。修正してください。

public static void extractResource(String embeddedFileName, String destinationPath)
    {
        var currentAssembly = Assembly.GetExecutingAssembly();
        var arrResources = currentAssembly.GetManifestResourceNames();
        foreach (var resourceName in arrResources)
        {
            if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
            {
                using (var resourceToSave = currentAssembly.GetManifestResourceStream(resourceName))
                {
                    using (var output = File.OpenWrite(destinationPath))
                        resourceToSave.CopyTo(output);
                    resourceToSave.Close();
                }
            }
        }
    }
1

私のバージョンは次のとおりです。ファイルを既存のアイテムとしてプロジェクトに追加し、ファイルのプロパティを「埋め込みリソース」に変更します

特定の場所にファイルを動的に抽出するには:(この例では、書き込み権限などの場所をテストしません)

    /// <summary>
    /// Extract Embedded resource files to a given path
    /// </summary>
    /// <param name="embeddedFileName">Name of the embedded resource file</param>
    /// <param name="destinationPath">Path and file to export resource to</param>
    public static void extractResource(String embeddedFileName, String destinationPath)
    {
        Assembly currentAssembly = Assembly.GetExecutingAssembly();
        string[] arrResources = currentAssembly.GetManifestResourceNames();
        foreach (string resourceName in arrResources)
            if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
            {
                Stream resourceToSave = currentAssembly.GetManifestResourceStream(resourceName);
                var output = File.OpenWrite(destinationPath);
                resourceToSave.CopyTo(output);
                resourceToSave.Close();
            }
    }
1
Fred B

必要に応じて、文字列として何かを抽出します。

public static string ExtractResourceAsString(String embeddedFileName)
    {
        var currentAssembly = Assembly.GetExecutingAssembly();
        var arrResources = currentAssembly.GetManifestResourceNames();
        foreach (var resourceName in arrResources)
        {
            if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
            {
                using (var resourceToSave = currentAssembly.GetManifestResourceStream(resourceName))
                {
                    using (var output = new MemoryStream())
                    {
                        resourceToSave.CopyTo(output);
                        return Encoding.ASCII.GetString(output.ToArray());
                    }
                }
            }
        }

        return string.Empty;
    }
0