2012-03-06 17 views
11

Mi objetivo es crear un archivo ejecutable que inicie una aplicación copiada en la sombra. El truco es que quiero que este programa de inicio no tenga dependencias externas y no tenga que contener ningún conocimiento sobre el programa que tiene que comenzar.¿Puede un ensamblado C# .dll contener un punto de entrada?

También quiero que sea el único ejecutable en el directorio. En otras palabras, quiero que "ejecute" un ensamblado .dll, no un ensamblado .exe. (Puedo requerir que el nombre del archivo .dll cargado en un nuevo dominio de aplicación sea el mismo cada vez, como Main.dll o algo así.)

Parecía que AppDomain.ExecuteAssembly haría exactamente lo que yo quería. Dice que comenzará la ejecución en el "punto de entrada especificado en el encabezado .NET Framework".

Cuando intento usar esa función, aparece el error "No se encontró el punto de entrada en el ensamblado 'DllApp'".

El programa de arranque que tengo, tratando de ejecutar el ensamblado:

static void Main() 
{ 
    AppDomain domain = AppDomain.CreateDomain("DllApp"); 
    domain.ExecuteAssembly("DllApp.dll"); 
} 

El código de la aplicación, en un archivo .dll, con un punto de entrada por defecto:

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 

This page on Main() functions dice que "Las bibliotecas y los servicios no requieren un método principal como punto de entrada". No dice que no puede tener un punto de entrada predeterminado tampoco.

He intentado todas las diversas permutaciones de vacío, un tipo de público/privado estática principal de retorno int, string [] args como argumentos, con un espacio de nombres, sin espacio de nombres, clase estática/no estática, etc.

Pude cambiar mi código para heredarlo de MarshalByRefObject y luego usar CreateInstance para crear un objeto, pero parece que unirá más el starter al programa que se supone que debe comenzar. Si pudiera usar ExecuteAssembly, la aplicación que se está iniciando solo necesitaría un vacío static Main, y eso es realmente simple y difícil de estropear.

¿Es posible que un ensamblado .dll tenga un punto de entrada predeterminado, y para que ExecuteAssembly lo encuentre, o simplemente tengo que resignarme a seguir otra ruta?

+1

No tiene sentido tener un punto de entrada para un ensamblado .NET (dll) ya que por sí solo no se inicia como un proceso. – Zenwalker

Respuesta

17

Puede compilar una aplicación .NET como un exe (que es un ensamblaje) y cambiarle el nombre a .DLL y actuará como un ensamblado normal .NET .dll. Entonces tendrá su punto de entrada.

+0

Esto funcionó perfectamente sin tener que cambiar nada más. Me pregunto por qué no pensé en eso ... Gracias Keith. – Sean

-1

La respuesta corta es no. un archivo .DLL es una biblioteca enlazada dinámicamente que es código llamado por otra biblioteca. Supongo que lo que Keith dijo que técnicamente funcionaría ... probablemente puedas cambiarle el nombre a lo que quieras, incluso .txt o .pdf, siempre y cuando comiences la aplicación de la manera adecuada. La principal pregunta que tengo es esto; ¿¿Que estás tratando de hacer?? A menos que intentes escribir malware, ¿por qué querrías hacer esto? No es que aprueben la escritura de malware para propósitos malos, pero sé que a la gente le gusta experimentar en su propio laboratorio, así que por mi parte no lo condeno. Si está escribiendo malware algo como C++, c o ensamblador podría ser una mejor apuesta, creo que C# podría hacer el trabajo, pero meh ...

+0

punto es que mi respuesta es que el compilador genera dlls o exes, pero ambos son ensamblados, simplemente son ensamblajes con un punto de entrada definido, que es lo que estaba pidiendo. –

+1

No, no hay malware escribiendo aquí. Estoy tratando de crear un pequeño programa de inicio para copiar mi aplicación principal. Luego puedo actualizar fácilmente mi aplicación principal sin tener que saltar a través de otros aros de ejecutables separados para la actualización, etc. Solo quería que el arrancador estuviera completamente desacoplado si fuera posible, luego podría usarlo con todas mis aplicaciones. – Sean

+0

"A menos que intentes escribir malware" ¡¡¡LOL !! –

0

Encontré el consejo no tan fácil de seguir. Después de experimentar un poco, así es como obtuve el éxito:

Creé una aplicación de consola con un main simple e incluí el resto del código de mi DLL original.A continuación se muestra un programa simplificado que incluye una DLL:

namespace FIT.DLLTest 
{ 
    public class DLLTest 
    { 
    [STAThread] 
    static void Main(string[] args) 
    { 
     int a = 1; 
    } 

    public DLLTest() 
    { 
     int b = 17; 
    } 

    public int Add(int int1, int int2) 
    { 
     return int1 + int2; 
    } 
    } 
} 

Después de la compilación que cambió el nombre del .exe generado para una DLL.

En el programa madre, que usa la DLL, primero agregué DLLTest.dll como referencia, luego agregué el código para ejecutar la DLL.

namespace TestDLLTest 
{ 
    class TestDLLTest 
    { 
    static void Main(string[] args) 
    { 
     AppDomain domain = AppDomain.CreateDomain("DLLTest"); 
     domain.ExecuteAssembly("DllTest.dll"); 

     DLLTest dt = new DLLTest(); 
     int res2 = dt.Add(6, 8); 
     int a = 1; 
    } 
    } 
} 

Viola pude ejecutar y añadir un punto de interrupción en el método DLLTest.Main y ver que podía invocar el principal de DLLTest. ¡Gracias por la discusión, amigos!

Cuestiones relacionadas