2009-04-28 29 views
27

¿Cómo incrusto un archivo ejecutable externo dentro de mi aplicación C# Windows Forms?Incrustar un archivo ejecutable externo dentro de un programa C#

Editar: Necesito incrustarlo porque es una aplicación de consola externa gratuita (hecha en C++) desde la que leo los valores de salida para usar en mi programa. Sería bueno y más profesional tenerlo incrustado.

El segundo motivo es un requisito para insertar un archivo de proyector Flash dentro de una aplicación .NET.

+2

La pregunta es: ¿qué es lo que desea con que "ejecutable externo"? si solo está incrustándolo y sacándolo, cuando "Recurso incrustado" – tofi9

+0

Y si simplemente está 'ejecutándolo y obteniendo su resultado', despliéguelo uno al lado del otro. No es necesario que esté incrustado. Del mismo modo que el archivo Flash, tu _podría simplemente implementarlo con tu programa, si eso es todo lo que realmente necesitas. Sospecho que tienes más ** necesidades ** que no te has molestado en enumerar. :) –

Respuesta

18

Aquí hay un código de ejemplo que sería más o menos lograr esto, menos la comprobación de errores de ningún tipo. Además, asegúrese de que la licencia del programa que se va a incrustar permita este tipo de uso.

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

La única parte difícil es conseguir el valor correcto para el primer argumento de ExtractResource. Debe tener el formato "namespace.name", donde el espacio de nombres es el espacio de nombre predeterminado para su proyecto (busque esto en Proyecto | Propiedades | Aplicación | Espacio de nombres predeterminado). La segunda parte es el nombre del archivo, que deberá incluir en su proyecto (asegúrese de establecer la opción de compilación en "Recurso incrustado"). Si coloca el archivo en un directorio, p. Recursos, entonces ese nombre se convierte en parte del nombre del recurso (por ejemplo, "myProj.Resources.Embedded.exe"). Si tiene problemas, intente abrir su binario compilado en Reflector y busque en la carpeta de Recursos. Los nombres enumerados aquí son los nombres que pasaría al GetManifestResourceStream.

+2

Ejem. GMRS es la VIEJA manera de hacer esto. Puede incrustar el .exe en el conjunto como una matriz de bytes a la que se puede acceder como una propiedad. Dos pasos para obtenerlo y guardarlo en el disco, en lugar de la monstruosidad con cuerdas mágicas que ha sugerido. [Aquí hay una página sobre cómo crear recursos fuertemente tipados en VS.] (http://msdn.microsoft.com/en-us/library/t69a74ty (VS.90) .aspx) – Will

+23

Lo siento, claramente este no es el la respuesta más actualizada, pero no estoy seguro de que realmente merezca llamarse "monstruosidad". – Charlie

4

¿El ejecutable es un ensamblado administrado? Si es así, puede usar ILMerge para fusionar ese ensamblaje con el suyo.

+1

¿Cómo lo diría? – beppe9000

12

sólo tiene que añadir a su proyecto y establezca la opción de generación de "Recurso incrustado"

5

Esta es probablemente la más simple:

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

¿Qué es myApp after Properties.Resources? ¿Es esta una clase custmo para el recurso embebido? – datelligence

+0

@datelligence myApp es su nombre de recurso personalizado. El que ha agregado/incrustado en su archivo de recursos. En mi caso, es un ejecutable con la extensión .exe. – nawfal

44

forma más simple, lo que conduce desde lo Will said:

  1. Añadir el .exe utilizando Resources.resx
  2. Código esto:

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

Por supuesto, es aconsejable comprobar si el archivo existe y/o eliminar el archivo después, según corresponda. –

+1

esto puede ser útil, ¿Qué es MyExecutable después de Properties.Resources. [MyExecutable], es este un objeto definido para el recurso embebido? – datelligence

1

aquí está mi versión: agregar el archivo al proyecto como un elemento existente, cambiar las propiedades del archivo a "Recurso incrustado"

Para extraer dinámicamente el archivo en un lugar determinado: (este ejemplo no prueba ubicación para permisos de escritura, 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(); 
      } 
    } 
1
  1. Añadir archivo a VS Proyecto
  2. Marcar como "Recurso incrustado" -> propiedades de archivo
  3. nombre utilizar para resolver: [nombre de la Asamblea] [nombre del. recurso incrustado] como "MyFunkyNTServcice.SelfDelete.bat"

Su código tiene una falla de recursos (no se liberó el identificador de archivo!), Por favor, corregir a:

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

Extracto algo como cadena, si es necesario:

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