How do I embed an external executable inside my C# Windows Forms application?
如何在C#Windows窗体应用程序中嵌入外部可执行文件?
Edit: I need to embed it because it's an external free console application (made in C++) from which I read the output values to use in my program. It would be nice and more professional to have it embedded.
编辑:我需要嵌入它,因为它是一个外部的免费控制台应用程序(用C ++编写),我从中读取要在我的程序中使用的输出值。嵌入它会更好,更专业。
Second reason is a requirement to embed a Flash projector file inside a .NET application.
第二个原因是需要在Flash应用程序中嵌入Flash投影仪文件。
8 个解决方案
#1
Here is some sample code that would roughly accomplish this, minus error checking of any sort. Also, please make sure that the license of the program to be embedded allows this sort of use.
下面是一些大致完成此操作的示例代码,减去任何类型的错误检查。另外,请确保要嵌入的程序的许可证允许这种使用。
// 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 );
The only tricky part is getting the right value for the first argument to ExtractResource
. It should have the form "namespace.name", where namespace is the default namespace for your project (find this under Project | Properties | Application | Default namespace). The second part is the name of the file, which you'll need to include in your project (make sure to set the build option to "Embedded Resource"). If you put the file under a directory, e.g. Resources, then that name becomes part of the resource name (e.g. "myProj.Resources.Embedded.exe"). If you're having trouble, try opening your compiled binary in Reflector and look in the Resources folder. The names listed here are the names that you would pass to GetManifestResourceStream
.
唯一棘手的部分是为ExtractResource的第一个参数获取正确的值。它应该具有“namespace.name”形式,其中namespace是项目的默认命名空间(在Project | Properties | Application | Default namespace下找到它)。第二部分是文件的名称,您需要将其包含在项目中(确保将构建选项设置为“嵌入式资源”)。如果您将文件放在目录下,例如资源,然后该名称成为资源名称的一部分(例如“myProj.Resources.Embedded.exe”)。如果遇到问题,请尝试在Reflector中打开已编译的二进制文件,然后查看Resources文件夹。此处列出的名称是您将传递给GetManifestResourceStream的名称。
#2
Simplest way, leading on from what Will said:
最简单的方法,从Will所说的:
- Add the .exe using Resources.resx
-
Code this:
string path = Path.Combine(Path.GetTempPath(), "tempfile.exe"); File.WriteAllBytes(path, MyNamespace.Properties.Resources.MyExecutable); Process.Start(path);
使用Resources.resx添加.exe
代码:string path = Path.Combine(Path.GetTempPath(),“tempfile.exe”); File.WriteAllBytes(path,MyNamespace.Properties.Resources.MyExecutable); 的Process.Start(路径);
#3
Just add it to your project and set the build option to "Embedded Resource"
只需将其添加到项目中并将构建选项设置为“Embedded Resource”
#4
This is probably the simplest:
这可能是最简单的:
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);
#5
Is the executable a managed assembly? If so you can use ILMerge to merge that assembly with yours.
可执行文件是托管程序集吗?如果是这样,您可以使用ILMerge将该程序集与您的程序集合并。
#6
Here's my version: Add the file to the project as an existing item, change the properties on the file to "Embedded resource"
这是我的版本:将文件作为现有项添加到项目中,将文件属性更改为“Embedded resource”
To dynamically extract the file to a given location: (this example doesn't test location for write permissions etc)
要将文件动态提取到给定位置:(此示例不测试写入权限的位置等)
/// <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();
}
}
#7
- Add File to VS Project
- Mark as "Embedded Resource" -> File properties
- Use name to resolve: [Assembly Name].[Name of embedded resource] like "MyFunkyNTServcice.SelfDelete.bat"
将文件添加到VS Project
标记为“嵌入式资源” - >文件属性
使用名称解析:[程序集名称]。[嵌入资源的名称],如“MyFunkyNTServcice.SelfDelete.bat”
Your code has resource bug (file handle not freed!), please correct to:
您的代码有资源错误(文件句柄未被释放!),请更正为:
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();
}
}
}
}
#8
Extract something as string, if needed:
如果需要,将字符串提取为字符串:
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;
}
#1
Here is some sample code that would roughly accomplish this, minus error checking of any sort. Also, please make sure that the license of the program to be embedded allows this sort of use.
下面是一些大致完成此操作的示例代码,减去任何类型的错误检查。另外,请确保要嵌入的程序的许可证允许这种使用。
// 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 );
The only tricky part is getting the right value for the first argument to ExtractResource
. It should have the form "namespace.name", where namespace is the default namespace for your project (find this under Project | Properties | Application | Default namespace). The second part is the name of the file, which you'll need to include in your project (make sure to set the build option to "Embedded Resource"). If you put the file under a directory, e.g. Resources, then that name becomes part of the resource name (e.g. "myProj.Resources.Embedded.exe"). If you're having trouble, try opening your compiled binary in Reflector and look in the Resources folder. The names listed here are the names that you would pass to GetManifestResourceStream
.
唯一棘手的部分是为ExtractResource的第一个参数获取正确的值。它应该具有“namespace.name”形式,其中namespace是项目的默认命名空间(在Project | Properties | Application | Default namespace下找到它)。第二部分是文件的名称,您需要将其包含在项目中(确保将构建选项设置为“嵌入式资源”)。如果您将文件放在目录下,例如资源,然后该名称成为资源名称的一部分(例如“myProj.Resources.Embedded.exe”)。如果遇到问题,请尝试在Reflector中打开已编译的二进制文件,然后查看Resources文件夹。此处列出的名称是您将传递给GetManifestResourceStream的名称。
#2
Simplest way, leading on from what Will said:
最简单的方法,从Will所说的:
- Add the .exe using Resources.resx
-
Code this:
string path = Path.Combine(Path.GetTempPath(), "tempfile.exe"); File.WriteAllBytes(path, MyNamespace.Properties.Resources.MyExecutable); Process.Start(path);
使用Resources.resx添加.exe
代码:string path = Path.Combine(Path.GetTempPath(),“tempfile.exe”); File.WriteAllBytes(path,MyNamespace.Properties.Resources.MyExecutable); 的Process.Start(路径);
#3
Just add it to your project and set the build option to "Embedded Resource"
只需将其添加到项目中并将构建选项设置为“Embedded Resource”
#4
This is probably the simplest:
这可能是最简单的:
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);
#5
Is the executable a managed assembly? If so you can use ILMerge to merge that assembly with yours.
可执行文件是托管程序集吗?如果是这样,您可以使用ILMerge将该程序集与您的程序集合并。
#6
Here's my version: Add the file to the project as an existing item, change the properties on the file to "Embedded resource"
这是我的版本:将文件作为现有项添加到项目中,将文件属性更改为“Embedded resource”
To dynamically extract the file to a given location: (this example doesn't test location for write permissions etc)
要将文件动态提取到给定位置:(此示例不测试写入权限的位置等)
/// <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();
}
}
#7
- Add File to VS Project
- Mark as "Embedded Resource" -> File properties
- Use name to resolve: [Assembly Name].[Name of embedded resource] like "MyFunkyNTServcice.SelfDelete.bat"
将文件添加到VS Project
标记为“嵌入式资源” - >文件属性
使用名称解析:[程序集名称]。[嵌入资源的名称],如“MyFunkyNTServcice.SelfDelete.bat”
Your code has resource bug (file handle not freed!), please correct to:
您的代码有资源错误(文件句柄未被释放!),请更正为:
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();
}
}
}
}
#8
Extract something as string, if needed:
如果需要,将字符串提取为字符串:
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;
}