埋め込まれたリソースの「パス」を見つけるにはどうすればよいですか?


110

PNGをアセンブリの埋め込みリソースとして保存しています。同じアセンブリ内から、私はこのようないくつかのコードを持っています:

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

"file.png"という名前のファイルは、(Visual Studio内の) "Resources"フォルダーに保存され、埋め込みリソースとしてマークされます。

コードは例外で失敗します:

リソースMyNamespace.Resources.file.pngがクラスMyNamespace.MyClassに見つかりません

機能する同じコード(別のアセンブリにあり、別のリソースを読み込む)があります。だから私はテクニックが音であることを知っています。私の問題は、正しいパスが何であるかを理解しようとすることに多くの時間を費やしてしまうことです。アセンブリーを(デバッガーなどで)クエリして、正しいパスを見つけることができれば、頭痛の種を減らすことができます。

回答:


198

これにより、すべてのリソースの文字配列が取得されます。

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

3
組み込みのhttpサーバーのルートディレクトリとして割り当てるためのリソースフォルダパスを取得するにはどうすればよいですか?
lazzy_ms 2018

45

私も毎回これを行う方法を忘れているので、小さなクラスで必要な2つのワンライナーをラップするだけです。

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

あなたのクラスは別の名前空間にあると思います。これを解決する標準的な方法は、リソースクラスと厳密に型指定されたリソースを使用することです。

ProjectNamespace.Properties.Resources.file

IDEのリソースマネージャを使用して、リソースを追加します。


私のクラスは別の名前空間にあります。Resourcesフォルダーは、プロジェクト構成でデフォルトの名前空間として指定されている名前空間の下にあるようですが、さまざまな理由で、このクラスが属する名前空間ではありません。別のアプローチを完全に使用することについてもあなたは正しいと思いますが、私はレガシーコードと一貫性を保つ必要があるため、それは私の制御を超えています。
Rob

7
これは、ファイルパスではなく、リソースを取得します。
うちはイタチ

3
@UchihaItachiだから、私はこの答えを別の(そして間違いなく標準的な)方法として明示的に提供しました。これは、質問に逐語的に答えるのではなく(すでに答えが出ている)のではなく、根本的な問題を解決する方法です。
Konrad Rudolph

1
@UchihaItachiこの質問は、質問をしている人が直面している問題、彼のアプローチとは何か、そして彼がこれまでにどのように試みてきたかを伝えます。ルドルフはこの質問に直接答えていませんが、問題を解決するための別のアプローチに取り組んでいます。ほとんどの場合、このアプローチはより便利で安全で一般的です。この答えは役に立ちます。なぜあなたは人々の答えを止めようとしないといけないのか理解できません。賛成/反対投票ボタンは理由があります。
Nin

5

次のメソッドを使用して、埋め込みリソースを取得します。

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

次に、プロジェクトのパスを使用してこれを呼び出します。

GetResourceStream(@"DirectoryPathInLibrary/Filename")

3

リソースの名前は、名前空間にファイルへのパスの「疑似」名前空間を加えたものです。「疑似」名前空間は、の代わりに¥(バックスラッシュ)を使用するサブフォルダー構造によって作成されます。(ドット)。

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

次の呼び出し:

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

名前空間my.namespaceのfolder-structure resources \ xmlにあるmy.xmlのストリームを返します。


6
また、フォルダー内のダッシュ( '-')は下線( '_')に置き換えられます。他の記号もあるかもしれません。同じ方法を使用できるように、コンパイラーがどのように実行しているかを確認したいと思います。
Boyko Karadzhov 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.