Làm cách nào để tôi có thể khám phá “đường dẫn” của một tài nguyên nhúng?


110

Tôi đang lưu trữ PNG dưới dạng tài nguyên được nhúng trong một hội đồng. Từ trong cùng một assembly, tôi có một số mã như thế này:

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

Tệp có tên "file.png" được lưu trữ trong thư mục "Tài nguyên" (trong Visual Studio) và được đánh dấu là tài nguyên nhúng.

Mã không thành công với một ngoại lệ nói:

Không thể tìm thấy tài nguyên MyNamespace.Resources.file.png trong lớp MyNamespace.MyClass

Tôi có mã giống hệt nhau (trong một hội đồng khác, tải một tài nguyên khác) hoạt động. Vì vậy, tôi biết kỹ thuật là âm thanh. Vấn đề của tôi là cuối cùng tôi đã dành rất nhiều thời gian để cố gắng tìm ra con đường chính xác là gì. Nếu tôi có thể chỉ cần truy vấn (ví dụ: trong trình gỡ lỗi) assembly để tìm đường dẫn chính xác, điều đó sẽ giúp tôi đỡ đau đầu.

Câu trả lời:


198

Điều này sẽ giúp bạn có được một mảng chuỗi gồm tất cả các tài nguyên:

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

3
Này, Làm cách nào để lấy đường dẫn Thư mục Tài nguyên để gán nó làm Dir gốc cho máy chủ http nhúng của tôi?
lazzy_ms

45

Tôi thấy mình cũng quên cách làm điều này vì vậy tôi chỉ quấn hai lớp lót một lớp mà tôi cần trong một lớp học nhỏ:

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

Tôi đoán rằng lớp của bạn nằm trong một không gian tên khác. Cách chuẩn tắc để giải quyết vấn đề này là sử dụng lớp tài nguyên và tài nguyên được đánh máy mạnh:

ProjectNamespace.Properties.Resources.file

Sử dụng trình quản lý tài nguyên của IDE để thêm tài nguyên.


Bạn nói đúng, lớp của tôi ở trong một không gian tên khác. Có vẻ như thư mục Tài nguyên nằm trong không gian tên được chỉ định làm không gian tên mặc định trong cấu hình dự án, vì nhiều lý do khác nhau không phải là không gian tên mà lớp này là một phần. Tôi nghi ngờ bạn cũng đúng khi sử dụng một cách tiếp cận khác hoàn toàn, nhưng vì tôi cần phải nhất quán với mã kế thừa, điều đó nằm ngoài tầm kiểm soát của tôi.
Rob

7
Điều này lấy tài nguyên - không phải là đường dẫn tệp.
Uchiha Itachi

3
@UchihaItachi Đó là lý do tại sao tôi đưa ra câu trả lời này một cách rõ ràng như một cách khác (và được cho là kinh điển) để giải quyết vấn đề cơ bản hơn là trả lời nguyên văn câu hỏi (đã có câu trả lời ở bất kỳ mức độ nào).
Konrad Rudolph

1
@UchihaItachi Câu hỏi cũng cho biết vấn đề mà người hỏi đang gặp phải, cách tiếp cận của anh ấy là gì và anh ấy đã cố gắng như thế nào cho đến nay. Mặc dù Rudolph không trực tiếp trả lời câu hỏi, nhưng ông đề cập đến một cách tiếp cận khác để giải quyết vấn đề. Trong hầu hết các trường hợp, cách tiếp cận này thuận tiện, an toàn và phổ biến hơn. Câu trả lời này là hữu ích. Tôi chỉ không hiểu tại sao bạn phải cố gắng chặn câu trả lời của mọi người. Các nút Bỏ phiếu Lên / Bỏ phiếu Xuống là có lý do.
Nin

5

Tôi sử dụng phương pháp sau để lấy tài nguyên nhúng:

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

Sau đó, tôi gọi điều này với đường dẫn trong dự án:

GetResourceStream(@"DirectoryPathInLibrary/Filename")

3

Tên của tài nguyên là không gian tên cộng với không gian tên "giả" của đường dẫn đến tệp. Không gian tên "giả" được tạo bởi cấu trúc thư mục con bằng cách sử dụng \ (dấu gạch chéo ngược) thay vì. (dấu chấm).

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

Cuộc gọi sau:

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

sẽ trả về luồng my.xml nằm trong tài nguyên cấu trúc thư mục \ xml trong không gian tên: my.namespace.


6
Ngoài ra, dấu gạch ngang ('-') trong các thư mục được thay thế bằng dấu gạch dưới ('_'). Có thể có các biểu tượng khác. Tôi muốn xem trình biên dịch đang hoạt động như thế nào để chúng ta có thể sử dụng cùng một phương pháp.
Boyko Karadzhov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.