2009-04-28 11 views
27

Come si incorpora un eseguibile esterno nella mia applicazione C# Windows Forms?Incorporamento di un eseguibile esterno all'interno di un programma C#

Modifica: Ho bisogno di incorporarlo perché è un'applicazione di console gratuita esterna (realizzata in C++) da cui ho letto i valori di uscita da utilizzare nel mio programma. Sarebbe bello e più professionale averlo incorporato.

Il secondo motivo è un requisito per incorporare un file di proiettore Flash all'interno di un'applicazione .NET.

+2

La domanda è: che cosa si vuole con quel "eseguibile esterno"? se solo lo si incorpora e lo si estrae, quando "Risorsa incorporata" – tofi9

+0

E se si tratta solo di "eseguirlo e ottenere l'output", quindi distribuirlo parallelamente. Non c'è bisogno che sia incorporato. Allo stesso modo del file Flash, il tuo _could_ lo distribuisca con il tuo programma, se è tutto ciò di cui hai veramente bisogno. Sospetto che tu abbia altri ** bisogni ** che non ti sei preso la briga di elencare. :) –

risposta

18

Ecco alcuni esempi di codice che grosso modo ottenere questo risultato, meno controllo degli errori di qualsiasi tipo. Inoltre, assicurarsi che la licenza del programma da incorporare consenta questo tipo di utilizzo.

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

L'unica parte difficile è ottenere il giusto valore per il primo argomento a ExtractResource. Dovrebbe avere la forma "namespace.name", dove namespace è lo spazio dei nomi predefinito per il tuo progetto (trova questo sotto Project | Properties | Application | Default namespace). La seconda parte è il nome del file, che dovrai includere nel tuo progetto (assicurati di impostare l'opzione di compilazione su "Risorsa incorporata"). Se metti il ​​file in una directory, ad es. Risorse, quindi quel nome diventa parte del nome della risorsa (ad esempio "myProj.Resources.Embedded.exe"). Se hai problemi, prova ad aprire il tuo binario compilato in Reflector e cerca nella cartella Risorse. I nomi elencati qui sono i nomi che si passerebbero a GetManifestResourceStream.

+2

Ahem. GMRS è il modo più antico per farlo. Puoi semplicemente incorporare l'exe nell'assembly come array di byte accessibile come una proprietà. Due passi per prenderlo e salvarlo su disco, invece della mostruosità con le stringhe magiche che hai suggerito. [Ecco una pagina su come creare risorse fortemente tipizzate in VS.] (http://msdn.microsoft.com/en-us/library/t69a74ty (VS.90) .aspx) – Will

+23

Siamo spiacenti, chiaramente questo non è il risposta più aggiornata, ma non sono sicuro che meriti davvero di essere definita una "mostruosità". – Charlie

4

L'eseguibile è un assembly gestito? In tal caso, è possibile utilizzare ILMerge per unire l'assieme con il proprio.

+1

Come lo gestirà? – beppe9000

12

Basta aggiungere al tuo progetto e impostare l'opzione build "embedded risorse"

5

Questo è probabilmente il più semplice:

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

cosa è myApp dopo Properties.Resources? Questa è una classe custmo per la risorsa incorporata? – datelligence

+0

@datelligence myApp è il nome della risorsa personalizzata. Quello che hai aggiunto/incorporato al tuo file di risorse. Nel mio caso è un eseguibile con estensione .exe. – nawfal

44

modo più semplice, che porta su da quello che Will said:

  1. Aggiungere l'exe utilizzando Resources.resx
  2. Codice questo:

+1

Ovviamente, è consigliabile verificare se il file esiste e/o eliminare il file in seguito, a seconda dei casi. –

+1

questo può essere utile, Che cosa è MyExecutable dopo Properties.Resources. [MyExecutable], è un oggetto definito per la risorsa embeded? – datelligence

1

Ecco la mia versione: aggiungere il file al progetto come un elemento esistente, modificare le proprietà del file di "risorsa embedded"

Per estrarre dinamicamente il file in una determinata posizione: (questo esempio non prova posizione per i permessi di scrittura, ecc)

/// <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. Aggiungi file alla VS Progetto
  2. Segna come "risorsa incorporata" -> proprietà file
  3. Usa nome per risolvere: [nome assembly] [nome. risorsa incorporata] come "MyFunkyNTServcice.SelfDelete.bat"

il codice ha bug risorsa (file manico non liberato!), Si prega di correggere 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

estratto qualcosa come stringa, se necessario:

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; 
    } 
Problemi correlati