2012-03-06 22 views
11

Il mio obiettivo è creare un eseguibile che avvii un'applicazione shadow copiata. Il trucco è che voglio che questo programma di avviamento non abbia dipendenze esterne e non debba contenere alcuna conoscenza sul programma che deve iniziare.Un assembly C# .dll può contenere un punto di ingresso?

Voglio anche che sia l'unico eseguibile nella directory. In altre parole, voglio che esegua un assembly .dll e non un assembly .exe. (Posso richiedere che il nome del file DLL è caricato in una nuova AppDomain essere lo stesso ogni volta, come Main.dll o qualcosa di simile.)

Sembrava AppDomain.ExecuteAssembly farebbe esattamente quello che volevo. Dice che inizierà l'esecuzione nel "punto di ingresso specificato nell'intestazione .NET Framework".

Quando si tenta di utilizzare tale funzione viene visualizzato l'errore "Punto di ingresso non trovato nell'assembly" DllApp "".

Il programma di avviamento che ho, solo cercando di eseguire il montaggio:

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

Il codice dell'applicazione, in un file dll, con un punto di voce predefinita:

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

This page on Main() functions afferma che "Le biblioteche e i servizi non richiedono un metodo Main come punto di ingresso". Non dice che non può avere un punto di ingresso predefinito.

Ho provato tutte le varie permutazioni di principale, di tipo pubblico/privato static void int di ritorno, string [] args come argomenti, con uno spazio dei nomi, senza spazio dei nomi, non statico-classe statica /, ecc

Sono stato in grado di modificare il mio codice per ereditarlo da MarshalByRefObject e quindi utilizzare CreateInstance per creare un oggetto, ma sembra che accoppierà più strettamente l'iniziatore al programma che dovrebbe iniziare. Se potessi usare ExecuteAssembly, l'applicazione avviata avrebbe solo bisogno di un vuoto statico Main, e questo è davvero semplice e difficile da rovinare.

È possibile che un assembly .dll abbia un punto di ingresso predefinito e che ExecuteAssembly lo trovi o devo semplicemente ripromettersi ad andare su un'altra rotta?

+1

Non ha senso avere un punto di ingresso per un assembly .NET (dll) che da solo non viene avviato come processo. – Zenwalker

risposta

17

È possibile compilare un'app .NET come un exe (che è un assembly) e rinominarlo in un file .DLL e funzionerà come un normale assembly .NET .dll. Avrà quindi il tuo punto di ingresso.

+0

Questo ha funzionato perfettamente senza dover cambiare altro. Mi chiedo perché non ci ho pensato ... Grazie Keith. – Sean

-1

Risposta breve no. un file .DLL è una libreria collegata dinamicamente che è chiamata da un'altra libreria. Immagino che ciò che Keith ha detto funzionerebbe tecnicamente .. probabilmente potresti rinominarlo in qualunque cosa tu voglia anche .txt o .pdf se avvii l'applicazione nel modo corretto. La domanda principale che ho è questa; Cosa stai cercando di fare?? A meno che tu non stia cercando di scrivere malware, perché vorresti farlo? Non che io condoni la scrittura di malware per scopi cattivi, ma so che alla gente piace sperimentare nel proprio laboratorio, quindi io per primo non lo condanno. Se stai scrivendo malware qualcosa come C++, c o assembler potrebbe essere una scommessa migliore, immagino che C# possa portare a termine il lavoro ma ...

+0

punto è con la mia risposta è che il compilatore genera o DLL o ex, ma entrambi sono assiemi, i suoi ex soli sono assiemi con un punto di ingresso definito, che è quello che stava chiedendo. –

+1

No, nessun malware scrive qui. Sto cercando di creare un piccolo programma di avvio per copiare in ombra la mia applicazione principale. Quindi posso aggiornare facilmente la mia applicazione principale senza dover passare attraverso altri file di eseguibili separati per l'aggiornamento, ecc. Volevo solo che l'antipasto fosse completamente disaccoppiato, se possibile, quindi potrei usarlo con tutte le mie applicazioni. – Sean

+0

"A meno che non stiate cercando di scrivere malware" LOL !! –

0

Ho trovato il consiglio non così facile da seguire. Dopo alcuni esperimenti, ho raggiunto il successo:

Ho creato un'applicazione console con un semplice main e incluso il resto del codice dalla mia DLL originale.Qui di seguito è un programma semplificato che include 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; 
    } 
    } 
} 

Dopo la compilazione ho rinominato il generato .exe per una DLL.

Nel programma madre, che utilizza la DLL, ho aggiunto per la prima volta DLLTest.dll come riferimento, quindi ho aggiunto il codice per eseguire 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 ho potuto eseguire e aggiungere un punto di interruzione nel metodo DLLTest.Main e vedere che ho potuto invocare la principale di DLLTest. Grazie per la discussione gente!

Problemi correlati