Ejecutar un ejecutable entro de un recurso

Iniciado por Meta, 29 Diciembre 2016, 22:04 PM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Hola:

Tengo un ejecutable llamado Validar.exe en un recurso.

Más información poner o quitar reursos.

He creado una palicación en consola con C#.
Código (csharp, 26) [Seleccionar]
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace Ejecutable_dentro_de_recursos_consola_01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Ejecuta Validar.exe dentro de C#.";
            Console.WriteLine("Funcionando C#...");
            CopiarRecurso(Assembly.GetExecutingAssembly(), "Recursos.Validar.exe", "Validar.exe");
            ProcessStartInfo info = new ProcessStartInfo("Validar.exe");
            Process.Start(info);

        }

        public static void CopiarRecurso(Assembly pAssembly, string pNombreRecurso, string pRuta)
        {
            using (Stream s = pAssembly.GetManifestResourceStream(pAssembly.GetName().Name + "." + pNombreRecurso))
            {
                if (s == null)
                {
                    throw new Exception("No se puede encontrar el recurso '" + pNombreRecurso + "'");
                }

                byte[] buffer = new byte[s.Length];
                s.Read(buffer, 0, buffer.Length);
                using (BinaryWriter sw = new BinaryWriter(File.Open(pRuta, FileMode.Create)))
                {
                    sw.Write(buffer);
                }
            }
        }
    }
}


Error:
Excepción no controlada del tipo 'System.Exception' en Ejecutable_dentro_de_recursos_consola_01.exe

Información adicional: No se puede encontrar el recurso 'Recursos.Validar.exe'


¿Algo se me escapa?

Ni poniendo la ruta completa, me hace caso. Da el mismo error.

Felices fiestas 2016.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/


Eleкtro

#2
Cuando añades un recurso al proyecto, se genera un archivo Xml que contiene los bytes serializados de ese recurso binario. En los recursos de la aplicación no se inserta un archivo .exe como tal.

- La metodología más cotidiana sería extraer los bytes de tu recurso binario para escribirlos en un archivo local, y luego, ejecutar ese archivo de forma corriente ...con las ventajas que proporciona la class Process.

- La metodología alternativa, y suponiendo que el archivo .exe sea un ensamblado .NET, sería pasarle la secuencia de bytes de tu recurso al método Assembly.Load() para crear un nuevo ensamblado (todo en memoria), leer el punto de entrada de la aplicación con la propiedad Assembly.EntryPoint, y por último llamar al método Assembly.CreateInstance() e invocar el método principal del ensamblado.

- La metodologia usando código no-administrado, sería llamando a la función Win32 VirtualAlloc como explican aquí: http://stackoverflow.com/questions/959087/is-it-possible-to-execute-an-x86-assembly-sequence-from-within-c/959144#959144

El siguiente código lo he sacado de mi API gratuita ElektroKit, allí puedes encontrar más utilidades interesantes para administrar los recursos.


( click en la imagen para visitar el código fuente y/o descargar la librería. )

Código original escrito en VB.NET:
Código (vbnet) [Seleccionar]
''' <summary>
''' Extracts a resource to disk.
''' </summary>
<DebuggerStepThrough>
Public Shared Sub ExtractResourceToDisk(ByVal resource As Byte(),
                                       ByVal targetFilepath As String,
                                       Optional ByVal overwrite As Boolean = False)

   Dim mode As FileMode
   If (overwrite) Then
       mode = FileMode.Create
   Else
       mode = FileMode.CreateNew
   End If

   Dim bufferSize As Integer = 4096
   Using fs As New FileStream(targetFilepath, mode, FileAccess.Write, FileShare.Read, bufferSize)
       fs.Write(resource, 0, resource.Length)
   End Using

End Sub


Conversión a C#:
Código (csharp) [Seleccionar]
/// <summary>
/// Extracts a resource to disk.
/// </summary>
[DebuggerStepThrough()]
public static void ExtractResourceToDisk(byte[] resource, string targetFilepath, bool overwrite = false) {

FileMode mode = default(FileMode);
if (overwrite) {
mode = FileMode.Create;
} else {
mode = FileMode.CreateNew;
}

int bufferSize = 4096;
using (FileStream fs = new FileStream(targetFilepath, mode, FileAccess.Write, FileShare.Read, bufferSize)) {
fs.Write(resource, 0, resource.Length);
}
}


Ejemplo de uso:
Código (csharp) [Seleccionar]
string filepath = Path.Combine(Path.GetTempPath(), "File.exe");
ExtractResourceToDisk(My.Resources.MyExecutableFile, filepath);
Process p = Process.Start(filepath);