在C#程序中嵌入外部可执行文件

时间:2009-04-28 15:55:56

标签: c# windows embed executable

如何在C#Windows窗体应用程序中嵌入外部可执行文件?

编辑:我需要嵌入它,因为它是一个外部的免费控制台应用程序(用C ++编写),我从中读取要在程序中使用的输出值。嵌入它会更好,也更专业。

第二个原因是需要在.NET应用程序中嵌入Flash投影仪文件。

8 个答案:

答案 0 :(得分:57)

最简单的方法,从Will said

开始
  1. 使用Resources.resx
  2. 添加.exe
  3. 编码:

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

答案 1 :(得分:20)

以下是一些大致可以实现此目的的示例代码,减去任何类型的错误检查。另外,请确保要嵌入的程序的许可证允许这种用途。

// 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”形式,其中namespace是项目的默认命名空间(在Project | Properties | Application | Default namespace下找到它)。第二部分是文件的名称,您需要将其包含在项目中(确保将构建选项设置为“嵌入式资源”)。如果您将文件放在目录下,例如资源,然后该名称成为资源名称的一部分(例如“myProj.Resources.Embedded.exe”)。如果遇到问题,请尝试在Reflector中打开已编译的二进制文件,然后查看Resources文件夹。此处列出的名称是您传递给GetManifestResourceStream的名称。

答案 2 :(得分:14)

只需将其添加到项目中,然后将构建选项设置为“Embedded Resource”

即可

答案 3 :(得分:7)

这可能是最简单的:

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);

答案 4 :(得分:4)

可执行文件是托管程序集吗?如果是这样,您可以使用ILMerge将该程序集与您的程序集合在一起。

答案 5 :(得分: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();
            }
    }

答案 6 :(得分:1)

  1. 将文件添加到VS Project
  2. 标记为“嵌入式资源” - &gt;文件属性
  3. 使用名称解析:[程序集名称]。[嵌入资源的名称],如“MyFunkyNTServcice.SelfDelete.bat”
  4. 您的代码有资源错误(文件句柄未被释放!),请更正:

    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();
                    }
                }
            }
        }
    

答案 7 :(得分:0)

如果需要,将字符串提取为字符串:

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;
    }