2010-12-10 55 views
7

Tengo un archivo INF guardado como un recurso incrustado en mi proyecto C#. Estoy tratando de guardar este archivo en una ubicación local a pedido. Estoy usando este métodoCopia de recurso incrustado como un archivo en el disco en C#

public static void SaveResourceToDisk(string ResourceName, string FileToExtractTo) 
{ 
    Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName); 
    FileStream resourceFile = new FileStream(FileToExtractTo, FileMode.Create); 

    byte[] b = new byte[s.Length + 1]; 
    s.Read(b, 0, Convert.ToInt32(s.Length)); 
    resourceFile.Write(b, 0, Convert.ToInt32(b.Length - 1)); 
    resourceFile.Flush(); 
    resourceFile.Close(); 

    resourceFile = null; 
} 

Cuando trato de llamar a este método (pasando el nombre del recurso junto con el nombre del espacio de nombres), me sale el error:

Object reference not set to an instance of an object

¿Qué estoy haciendo mal aquí?

+0

Si publicó el error completo (incluido el número de línea, que coincide con el número de línea de su código) puede ayudar a diagnosticar el problema. –

+2

Un consejo: Considere usar la palabra clave "usar" con sus objetos para deshacerse de ellos automáticamente. –

+2

Duplicado de http://stackoverflow.com/questions/864140/write-file-from-assembly-resource-stream-to-disk, que tiene un ejemplo de código más útil. – pennyrave

Respuesta

9

Se podría llamar

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames(); 

e inspeccionar el que los recursos incrustados son accesibles. Entonces puedes comparar eso con lo que estás pasando para ver si realmente estás logrando lo que esperabas.

Además, se debe considerar el uso de palabras clave para disponer de sus fuentes:

using(FileStream ResourceFile = new FileStream(FileToExtractTo, FileMode.Create)) 
{ 
    //do stuff 
} 

Buena suerte.

+0

De acuerdo, lo tengo. Estaba usando 'GetManifestResourceStream (namespace.resourcename)' cuando debería haber sido usado 'GetManifestResourceStream (namespace.Resources.resourcename)'. ¡Y gracias por la sugerencia de 'usar'! – GPX

4

Ésta es la manera más fácil de ahorrar un recurso incrustado:

var stream = assembly.GetManifestResourceStream("name of the manifest resourse"); 
    var fileStream = File.Create(@"C:\Test.xml"); 
    stream.Seek(0, SeekOrigin.Begin); 
    stream.CopyTo(fileStream); 
    fileStream.Close(); 
0

descomprime todos los recursos incrustados dentro de un conjunto y las guarda junto con el conjunto que contiene esta clase, manteniendo la estructura de directorios. Este código no requiere que usted sepa nada sobre los archivos contenidos en el ensamblado y es una solución más genérica, pero supone que todos los archivos tienen extensiones de archivo.

public class EmbeddedResources 
{ 
    private bool isUnpacked = false; 

    public async Task EnsureUnpacked(string saveDirectory) 
    { 
     if (!this.isUnpacked) 
     { 
      var assembly = Assembly.GetExecutingAssembly(); 
      var assemblyDirectory = Path.GetDirectoryName(assembly.Location); 
      foreach (var name in assembly.GetManifestResourceNames()) 
      { 
       var stream = assembly.GetManifestResourceStream(name); 

       var stringBuilder = new StringBuilder(); 
       var parts = name 
        .Replace(typeof(EmbeddedResources).Namespace + ".", string.Empty) 
        .Split('.') 
        .ToList(); 
       for (int i = 0; i < parts.Count; ++i) 
       { 
        var part = parts[i]; 
        if (string.Equals(part, string.Empty)) 
        { 
         stringBuilder.Append(".");  // Append '.' in file name. 
        } 
        else if (i == parts.Count - 2) 
        { 
         stringBuilder.Append(part);  // Append file name and '.'. 
         stringBuilder.Append('.'); 
        } 
        else if (i == parts.Count - 1) 
        { 
         stringBuilder.Append(part);  // Append file extension. 
        } 
        else 
        { 
         stringBuilder.Append(part);  // Append file path. 
         stringBuilder.Append('\\'); 
        } 
       } 

       var filePath = Path.Combine(saveDirectory, stringBuilder.ToString()); 
       using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) 
       { 
        await stream.CopyToAsync(fileStream); 
       } 
      } 

      this.isUnpacked = true; 
     } 
    } 
} 
Cuestiones relacionadas