Come posso scoprire il "percorso" di una risorsa incorporata?


110

Sto memorizzando un PNG come risorsa incorporata in un assembly. Dallo stesso assembly ho un codice come questo:

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

Il file, denominato "file.png" è archiviato nella cartella "Resources" (all'interno di Visual Studio) ed è contrassegnato come risorsa incorporata.

Il codice fallisce con un'eccezione che dice:

La risorsa MyNamespace.Resources.file.png non può essere trovata nella classe MyNamespace.MyClass

Ho un codice identico (in un assembly diverso, caricamento di una risorsa diversa) che funziona. Quindi so che la tecnica è valida. Il mio problema è che finisco per passare molto tempo a cercare di capire qual è il percorso corretto. Se potessi semplicemente interrogare (es. Nel debugger) l'assembly per trovare il percorso corretto, mi risparmierebbe un carico di mal di testa.

Risposte:


198

Questo ti darà un array di stringhe di tutte le risorse:

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

3
Ehi, come posso ottenere il percorso della cartella delle risorse per assegnarlo come directory principale per il mio server http incorporato?
lazzy_ms

45

Mi ritrovo a dimenticare come farlo anche ogni volta, quindi mi limito a racchiudere le due battute di cui ho bisogno in una piccola lezione:

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();
    }
}

19

Immagino che la tua classe si trovi in ​​uno spazio dei nomi diverso. Il modo canonico per risolvere questo problema sarebbe utilizzare la classe delle risorse e una risorsa fortemente tipizzata:

ProjectNamespace.Properties.Resources.file

Usa il gestore delle risorse dell'IDE per aggiungere risorse.


Hai ragione, la mia classe si trova in uno spazio dei nomi diverso. Sembra che la cartella Resources risieda nello spazio dei nomi specificato come spazio dei nomi predefinito nella configurazione del progetto, che per vari motivi non è lo spazio dei nomi di cui fa parte questa classe. Sospetto che tu abbia ragione anche sull'utilizzo di un approccio completamente diverso, ma poiché ho bisogno di essere coerente con il codice legacy, è al di fuori del mio controllo.
Rob

7
Questo afferra la risorsa, non il percorso del file.
Uchiha Itachi

3
@UchihaItachi Ecco perché ho offerto questa risposta esplicitamente come un altro (e probabilmente il canonico) modo di risolvere il problema sottostante piuttosto che rispondere alla domanda alla lettera (che ha già una risposta in ogni caso).
Konrad Rudolph

1
@UchihaItachi La domanda racconta anche il problema che la persona che fa la domanda sta affrontando, qual è il suo approccio e come ha provato finora. Sebbene Rudolph non risponda direttamente alla domanda, affronta un altro approccio per risolvere il problema. Nella maggior parte dei casi, questo approccio è più conveniente, sicuro e comune. Questa risposta è utile. Non capisco perché devi cercare di bloccare le risposte delle persone. I pulsanti Vota su / Vota giù sono presenti per un motivo.
Nin

5

Uso il seguente metodo per acquisire le risorse incorporate:

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

Quindi lo chiamo con il percorso nel progetto:

GetResourceStream(@"DirectoryPathInLibrary/Filename")

3

Il nome della risorsa è lo spazio dei nomi più lo spazio dei nomi "pseudo" del percorso del file. Lo spazio dei nomi "pseudo" viene creato dalla struttura delle sottocartelle utilizzando \ (barre rovesciate) invece di. (punti).

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

La seguente chiamata:

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

restituirà il flusso di my.xml che si trova nella struttura di cartelle resources \ xml nello spazio dei nomi: mio.namespace.


6
Anche i trattini ("-") nelle cartelle vengono sostituiti da trattini bassi ("_"). Potrebbero esserci anche altri simboli. Mi piacerebbe vedere come lo fa il compilatore in modo da poter utilizzare lo stesso metodo.
Boyko Karadzhov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.