Bagaimana cara menemukan "jalur" dari sumber daya yang disematkan?

110

Saya menyimpan PNG sebagai sumber daya yang disematkan dalam sebuah assembly. Dari dalam majelis yang sama saya memiliki beberapa kode seperti ini:

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

File, bernama "file.png" disimpan di folder "Resources" (dalam Visual Studio), dan ditandai sebagai resource yang disematkan.

Kode gagal dengan pengecualian yang mengatakan:

Resource MyNamespace.Resources.file.png tidak dapat ditemukan di kelas MyNamespace.MyClass

Saya memiliki kode identik (dalam rakitan berbeda, memuat sumber daya berbeda) yang berfungsi. Jadi saya tahu tekniknya adalah suara. Masalah saya adalah saya akhirnya menghabiskan banyak waktu untuk mencoba mencari tahu jalan yang benar. Jika saya bisa menanyakan (misalnya di debugger) perakitan untuk menemukan jalur yang benar, itu akan menyelamatkan saya dari beban sakit kepala.

rampok
sumber

Jawaban:

198

Ini akan memberi Anda array string dari semua sumber daya:

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
John
sumber
3
Hai, Bagaimana cara mendapatkan jalur Folder Sumber Daya untuk menetapkannya sebagai Dir root untuk server http tertanam saya?
lazzy_ms
45

Saya mendapati diri saya lupa bagaimana melakukan ini setiap saat, jadi saya hanya membungkus dua baris satu yang saya butuhkan di sebuah kelas kecil:

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

Saya menduga bahwa kelas Anda berada di namespace yang berbeda. Cara kanonik untuk menyelesaikannya adalah dengan menggunakan kelas sumber daya dan sumber daya yang sangat diketik:

ProjectNamespace.Properties.Resources.file

Gunakan pengelola sumber daya IDE untuk menambahkan sumber daya.

Konrad Rudolph
sumber
Anda benar, kelas saya berada di namespace yang berbeda. Tampaknya folder Resources berada di bawah namespace yang ditentukan sebagai namespace default dalam konfigurasi project, yang karena berbagai alasan bukan namespace kelas ini. Saya curiga Anda juga benar tentang menggunakan pendekatan yang berbeda sepenuhnya, tetapi karena saya harus konsisten dengan kode lama, itu di luar kendali saya.
Rob
7
Ini mengambil sumber daya - bukan jalur file.
Uchiha Itachi
3
@UchihaItachi Itulah mengapa saya menawarkan jawaban ini secara eksplisit sebagai cara lain (dan bisa dibilang kanonik) untuk memecahkan masalah yang mendasarinya daripada menjawab pertanyaan secara verbatim (yang sudah memiliki jawaban pada tingkat apa pun).
Konrad Rudolph
1
@UchihaItachi Pertanyaan ini juga menjelaskan masalah yang dihadapi orang yang bertanya, apa pendekatannya dan bagaimana dia telah mencoba sejauh ini. Meskipun Rudolph tidak langsung menjawab pertanyaan tersebut, dia membahas pendekatan lain untuk menyelesaikan masalah tersebut. Dalam kebanyakan kasus, pendekatan ini lebih nyaman, aman, dan umum. Jawaban ini sangat membantu. Saya hanya tidak mengerti mengapa Anda harus mencoba menutup jawaban orang. Tombol Vote Up / Vote Down ada karena suatu alasan.
Nin
5

Saya menggunakan metode berikut untuk mengambil sumber daya yang disematkan:

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

Saya kemudian menyebutnya dengan jalur dalam proyek:

GetResourceStream(@"DirectoryPathInLibrary/Filename")
masterwok
sumber
3

Nama sumber daya adalah ruang nama ditambah ruang nama "palsu" dari jalur ke file. Ruang nama "pseudo" dibuat oleh struktur sub folder menggunakan \ (garis miring terbalik), bukan. (titik).

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

Panggilan berikut:

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

akan mengembalikan aliran my.xml yang terletak di folder-struktur sumber daya \ xml di ruang nama: my.namespace.

pengguna3356450
sumber
6
Juga tanda hubung ('-') di folder diganti dengan garis bawah ('_'). Mungkin ada simbol lain juga. Saya ingin melihat bagaimana kompilator melakukannya sehingga kita dapat menggunakan metode yang sama.
Boyko Karadzhov