Gömülü bir kaynağın "yolunu" nasıl keşfedebilirim?


110

Bir PNG'yi bir derlemede gömülü bir kaynak olarak depoluyorum. Aynı derlemeden şuna benzer bir kodum var:

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

"File.png" adlı dosya "Kaynaklar" klasöründe (Visual Studio içinde) depolanır ve katıştırılmış bir kaynak olarak işaretlenir.

Kod şu istisnayla başarısız olur:

Kaynak MyNamespace.Resources.file.png, MyNamespace.MyClass sınıfında bulunamıyor

Çalışan aynı kodum var (farklı bir derlemede, farklı bir kaynak yükleniyor). Bu yüzden tekniğin sağlam olduğunu biliyorum. Benim sorunum, doğru yolun ne olduğunu anlamaya çalışmak için çok zaman harcamak. Doğru yolu bulmak için montajı basitçe sorgulayabilseydim (örneğin, hata ayıklayıcıda), bu beni bir sürü baş ağrısından kurtarırdı.

Yanıtlar:


198

Bu size tüm kaynakların bir dizi dizisini verecektir:

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

3
Hey, Gömülü http sunucum için kök dizin olarak atamak üzere Kaynak Klasörü yolunu nasıl edinebilirim?
lazzy_ms

45

Kendimi de her seferinde bunu nasıl yapacağımı unuturken buluyorum, bu yüzden ihtiyacım olan iki tek astarı küçük bir sınıfta paketliyorum:

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

Sınıfınızın farklı bir ad alanında olduğunu tahmin ediyorum. Bunu çözmenin kanonik yolu, kaynaklar sınıfını ve güçlü bir şekilde yazılmış bir kaynağı kullanmak olacaktır:

ProjectNamespace.Properties.Resources.file

Kaynakları eklemek için IDE'nin kaynak yöneticisini kullanın.


Haklısın, sınıfım farklı bir isim alanında. Kaynaklar klasörü, proje yapılandırmasında varsayılan ad alanı olarak belirtilen ad alanı altında yaşıyor gibi görünüyor; bu, çeşitli nedenlerle bu sınıfın parçası olduğu ad alanı değil. Tamamen farklı bir yaklaşım kullanma konusunda da haklı olduğunuzdan şüpheleniyorum, ancak eski kodla tutarlı olmam gerektiğinden, bu benim kontrolüm dışında.
Rob

7
Bu, kaynağı alır - dosya yolu değil.
Uchiha Itachi

3
@UchihaItachi İşte bu yüzden bu yanıtı , soruyu kelimesi kelimesine yanıtlamaktan ziyade (ki zaten bir cevabı olan) temeldeki sorunu çözmenin başka (ve muhtemelen kanonik) bir yolu olarak açık bir şekilde sundum .
Konrad Rudolph

1
@UchihaItachi Soru aynı zamanda soran kişinin karşılaştığı sorunu, yaklaşımının ne olduğunu ve şimdiye kadar nasıl denediğini de anlatır. Rudolph soruyu doğrudan cevaplamasa da, sorunu çözmek için başka bir yaklaşıma değiniyor. Çoğu durumda, bu yaklaşım daha rahat, güvenli ve yaygındır. Bu cevap faydalıdır. Sadece neden insanların cevaplarını kapatmaya çalıştığını anlamıyorum. Yukarı Oy / Aşağı Oy düğmeleri bir nedenden dolayı oradadır.
Nin

5

Gömülü kaynakları almak için aşağıdaki yöntemi kullanıyorum:

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

Daha sonra bunu projedeki yolla çağırıyorum:

GetResourceStream(@"DirectoryPathInLibrary/Filename")

3

Kaynağın adı, ad alanı artı dosyaya giden yolun "sözde" ad alanıdır. "Sözde" ad alanı, alt klasör yapısı tarafından yerine \ (ters eğik çizgi) kullanılarak oluşturulur. (Nokta).

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

Aşağıdaki çağrı:

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

ad alanı: my.namespace klasör yapısındaki kaynaklar \ xml klasöründe bulunan my.xml akışını döndürür.


6
Ayrıca klasörlerdeki kısa çizgiler ('-') alt çizgilerle ('_') değiştirilir. Başka semboller de olabilir. Derleyicinin bunu nasıl yaptığını görmek isterim, böylece aynı yöntemi kullanabiliriz.
Boyko Karadzhov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.