2012-05-02 14 views
16

Nella mia applicazione compilo un altro programma da file Source.cs utilizzando CodeDom.Compiler e ho incorporare alcune risorse (file EXE e DLL) al momento della compilazione usando:Come leggere una risorsa incorporata come matrice di byte senza scriverla sul disco?

// .... rest of code 

if (provider.Supports(GeneratorSupport.Resources)) 
{ 
    cp.EmbeddedResources.Add("MyFile.exe"); 
} 
if (provider.Supports(GeneratorSupport.Resources)) 
{ 
    cp.EmbeddedResources.Add("New.dll"); 
} 
// ....rest of code 

Nel file compilato, ho bisogno di leggere le risorse incorporate come matrice di byte. Ora sto facendo che con l'estrazione delle risorse su disco utilizzando la funzione qui sotto e l'uso

File.ReadAllBytes("extractedfile.exe"); 
File.ReadAllBytes("extracteddll.dll"); 

Lo faccio dopo aver estratto i due file su disco utilizzando questa funzione:

public static void ExtractSaveResource(String filename, String location) 
{ 
    // Assembly assembly = Assembly.GetExecutingAssembly(); 
    System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); 
    // Stream stream = assembly.GetManifestResourceStream("Installer.Properties.mydll.dll"); // or whatever 
    // string my_namespace = a.GetName().Name.ToString(); 
    Stream resFilestream = a.GetManifestResourceStream(filename); 
    if (resFilestream != null) 
    { 
     BinaryReader br = new BinaryReader(resFilestream); 
     FileStream fs = new FileStream(location, FileMode.Create); // say 
     BinaryWriter bw = new BinaryWriter(fs); 
     byte[] ba = new byte[resFilestream.Length]; 
     resFilestream.Read(ba, 0, ba.Length); 
     bw.Write(ba); 
     br.Close(); 
     bw.Close(); 
     resFilestream.Close(); 
    } 
    // this.Close(); 
} 

Come posso fai la stessa cosa (Ottieni le risorse incorporate come array di byte) ma senza scrivere nulla sul disco rigido?

risposta

23

Si sta già leggendo il flusso su un array di byte, perché non fermarsi qui?

public static byte[] ExtractResource(String filename) 
{ 
    System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); 
    using (Stream resFilestream = a.GetManifestResourceStream(filename)) 
    { 
     if (resFilestream == null) return null; 
     byte[] ba = new byte[resFilestream.Length]; 
     resFilestream.Read(ba, 0, ba.Length); 
     return ba; 
    } 
} 

modifica: visualizza i commenti per un motivo di lettura preferibile.

+1

Aggiornamento della mia risposta, non c'è bisogno di un flusso di memoria quando state già leggendo il flusso su un array di byte. – Rotem

+2

Potrebbe non funzionare correttamente, perché 'Stream.Read()' potrebbe non restituire tutti i dati in un 'Read()'. Non sono sicuro di come si comporta questo specifico 'Stream', ma per essere sicuri utilizzerei un' MemoryStream', 'CopyTo()' per questo e poi useremo 'ToArray()'. – svick

+0

@svick: hai ragione. In alternativa, si può usare lo schema di lettura descritto nell'esempio in questa pagina: http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx – Rotem