Як я можу виявити "шлях" вбудованого ресурсу?


110

Я зберігаю PNG як вбудований ресурс у зборі. Зсередини цієї ж збірки у мене є такий код:

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

Файл під назвою "file.png" зберігається у папці "Ресурси" (в межах Visual Studio) і позначається як вбудований ресурс.

Код не вдається за винятком:

Ресурс MyNamespace.Resources.file.png не можна знайти в класі MyNamespace.MyClass

У мене ідентичний код (в іншій збірці, завантаження іншого ресурсу), який працює. Тому я знаю, що техніка - це звук. Моя проблема полягає в тому, що я закінчую витрачати багато часу, намагаючись зрозуміти, який правильний шлях. Якби я міг просто запитати (наприклад, у налагоджувачі) збірку, щоб знайти правильний шлях, це врятувало б мене від головного болю.

Відповіді:


198

Ви отримаєте рядок з усіх ресурсів:

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

3
Ей, як я можу отримати шлях до папки ресурсів, щоб призначити його кореневим диром для мого вбудованого http-сервера?
lazzy_ms

45

Мені здається, що я забуваю, як це робити щоразу, тому я просто загортаю два однокласниці, які мені потрібні в невеликому класі:

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 для додавання ресурсів.


Ви маєте рацію, мій клас знаходиться в іншому просторі імен. Здається, що папка "Ресурси" живе у просторі імен, визначеному як простір імен за замовчуванням у конфігурації проекту, який з різних причин не є простором імен, до складу якого входить цей клас. Я підозрюю, що ви також правильні щодо використання іншого підходу цілком, але, оскільки мені потрібно відповідати застарілому коду, це поза моїм контролем.
Роб

7
Це захоплює ресурс - це не шлях до файлу.
Uchiha Itachi

3
@UchihaItachi Ось чому я запропонував цю відповідь прямо як інший (і, мабуть, канонічний) спосіб вирішення основної проблеми, а не дословно відповісти на питання (на яке вже відповідь у будь-якому разі).
Конрад Рудольф

1
@UchihaItachi Питання також розповідає про проблему, з якою стикається запитуючий, який його підхід та як він намагався до цього часу. Хоча Рудольф прямо не відповідає на питання, він вирішує інший підхід до вирішення проблеми. У більшості випадків такий підхід є більш зручним, безпечним та поширеним. Ця відповідь корисна. Я просто не розумію, чому потрібно намагатися закрити відповіді людей. Кнопки "Голосувати" / "Голосувати вниз" є з якоїсь причини.
Нін

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.xml, що знаходиться в ресурсах структури папки \ xml в просторі імен: my.namespace.


6
Також тире ('-') у папках замінюється підкресленнями ('_'). Можуть бути й інші символи. Я хотів би побачити, як це робить компілятор, щоб ми могли використовувати той самий метод.
Бойко Караджов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.