2008-08-26 3 views
81

Ich speichere ein PNG als eingebettete Ressource in einer Assembly. Von innerhalb derselben Baugruppe habe ich einige Code wie folgt aus:Wie kann ich den "Pfad" einer eingebetteten Ressource erkennen?

Bitmap image = new Bitmap(typeof(MyClass), "Resources.file.png"); 

Die Datei mit dem Namen „file.png“ in der „Ressourcen“ Ordner gespeichert (in Visual Studio) und wird als eingebettete Ressource markiert.

Der Code schlägt mit einer Ausnahme zu sagen:

Ressourcen MyNamespace.Resources.file.png kann nicht in Klasse MyNamespace.MyClass

Ich habe identischen Code (in einer anderen Anordnung zu finden, eine andere Ressource laden), die funktioniert. Also ich weiß, dass die Technik solide ist. Mein Problem ist, dass ich am Ende viel Zeit damit verbringe herauszufinden, was der richtige Weg ist. Wenn ich die Assembly einfach abfragen könnte (zB im Debugger), um den richtigen Pfad zu finden, würde mir das eine Menge Kopfschmerzen ersparen.

Antwort

156

Diese erhalten Sie einen String Array aller Ressourcen:

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

Ziemlich nützlich! Vielen Dank! –

15

Ich vermute, dass Ihre Klasse in einem anderen Namensraum ist. Der kanonische Weg, dies zu lösen wäre, die Ressourcen-Klasse zu verwenden und eine stark typisierte Ressource:

ProjectNamespace.Properties.Resources.file 

der Ressourcen-Manager IDE verwenden Ressourcen hinzuzufügen.

+0

Sie haben Recht, meine Klasse in einem anderen Namespace ist. Anscheinend befindet sich der Ordner Resources unter dem Namespace, der in der Projektkonfiguration als Standard-Namespace angegeben ist. Aus verschiedenen Gründen ist dies nicht der Namespace, zu dem diese Klasse gehört. Ich vermute, dass Sie auch über einen anderen Ansatz völlig korrekt sind, aber da ich mit Legacy-Code konsistent sein muss, ist das außerhalb meiner Kontrolle. – Rob

+0

Dies packt die Ressource - nicht den Dateipfad. –

+0

@UchihaItachi Deshalb habe ich diese Antwort ausdrücklich als eine andere (und wohl kanonische) Art der Lösung des * zugrunde liegenden Problems * angeboten, anstatt die Frage wortwörtlich zu beantworten (was ohnehin schon eine Antwort hat). –

41

ich mich zu vergessen, wie das geht auch jedes Mal tun, damit ich die beiden Einzeiler nur wickeln, die ich in einem kleinen brauchen Klasse:

public class Utility 
{ 
    /// <summary> 
    /// Takes the full name of a resource and loads it in to a stream. 
    /// </summary> 
    /// <param name="resourceName">Assuming an embedded resource is a file 
    /// called info.png and is located in a folder called Resources, it 
    /// will be compiled in to the assembly with this fully qualified 
    /// name: Full.Assembly.Name.Resources.info.png. That is the string 
    /// that you should pass to this method.</param> 
    /// <returns></returns> 
    public static Stream GetEmbeddedResourceStream(string resourceName) 
    { 
     return Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); 
    } 

    /// <summary> 
    /// Get the list of all emdedded resources in the assembly. 
    /// </summary> 
    /// <returns>An array of fully qualified resource names</returns> 
    public static string[] GetEmbeddedResourceNames() 
    { 
     return Assembly.GetExecutingAssembly().GetManifestResourceNames(); 
    } 
} 
3

der Name der Ressource ist der Namensraum plus der „Pseudo“ Namensraum des Pfades zur Datei. Der Pseudo-Namespace wird durch die Unterverzeichnisstruktur mit \ (Backslashes) anstelle von. (Punkte)

public static Stream GetResourceFileStream(String nameSpace, String filePath) 
{ 
    String pseduoName = filePath.Replace('\\', '.'); 
    Assembly assembly = Assembly.GetExecutingAssembly(); 
    return assembly.GetManifestResourceStream(nameSpace + "." + pseduoName); 
} 

Der folgende Aufruf:

GetResourceFileStream("my.namespace", "resources\\xml\\my.xml") 

den Strom von my.xml in den Ordner-Struktur resources \ xml im Namensraum befindet sich zurück: my.namespace.

+4

Auch Bindestriche ('-') in den Ordnern werden durch Unterstriche ('_') ersetzt. Es könnte auch andere Symbole geben. Ich würde gerne sehen, wie der Compiler es macht, damit wir die gleiche Methode verwenden können. –

5

Ich verwende die folgende Methode eingebettete Ressourcen zu greifen:

protected static Stream GetResourceStream(string resourcePath) 
    { 
     Assembly assembly = Assembly.GetExecutingAssembly(); 
     List<string> resourceNames = new List<string>(assembly.GetManifestResourceNames()); 

     resourcePath = resourcePath.Replace(@"/", "."); 
     resourcePath = resourceNames.FirstOrDefault(r => r.Contains(resourcePath)); 

     if (resourcePath == null) 
      throw new FileNotFoundException("Resource not found"); 

     return assembly.GetManifestResourceStream(resourcePath); 
    } 

ich diese dann in dem Projekt mit dem Pfad nennen:

GetResourceStream(@"DirectoryPathInLibrary/Filename")