2014-02-07 2 views
50

Это приложение, C# .NET 4.0:GetManifestResourceStream возвращает NULL

Я встраивание текстового файла в качестве ресурса, а затем пытаюсь отобразить его в диалоговом окне:

var assembly = Assembly.GetExecutingAssembly(); 
    var resourceName = "MyProj.Help.txt"; 

     using (Stream stream = assembly.GetManifestResourceStream(resourceName)) 
     { 
      using (StreamReader reader = new StreamReader(stream)) 
      { 
       string result = reader.ReadToEnd(); 
       System.Windows.Forms.MessageBox.Show(result, "MyProj", MessageBoxButtons.OK); 
      } 
     } 

Решением является MyProjSolution и исполняемый файл MyProj.exe. Help.txt - встроенный ресурс. Однако поток имеет значение NULL. Я пробовал MyProjSolution.Help.txt и MyProjSolution.MyProj.Help.txt, но ничего не работает.

+1

Используйте ildasm.exe, чтобы посмотреть имена .mresource в манифесте сборки. Не впадайте в эту яму нищеты, вместо этого используйте Project + Properties, вкладку Resource. Таким образом, вы можете просто использовать Properties.Resources.Help в своем исходном коде. –

ответ

107

Вы можете проверить, что ресурсы правильно внедренный с помощью

//From the assembly where this code lives! 
this.GetType().Assembly.GetManifestResourceNames() 

//or from the entry point to the application - there is a difference! 
Assembly.GetExecutingAssembly().GetManifestResourceNames() 

при отладке. В нем будут перечислены все (полностью квалифицированные имена) всех ресурсов, встроенных в сборку, в которой написан ваш код.

См. Assembly.GetManifestResourceNames() на MSDN.

Просто скопируйте соответствующее имя и используйте это вместо того, что вы определили в переменной «resourceName».

Примечания - имя ресурса чувствительно к регистру, и если вы неправильно ввели файл ресурсов, он не будет отображаться в списке, возвращаемом вызовом GetManifestResourceNames(). Также - убедитесь, что вы читаете ресурс из правильной сборки (если используются несколько сборок) - все это легко получить из текущей исполняемой сборки, а не из ссылочной сборки.

EDIT - .NET Ядро
Пожалуйста, ознакомьтесь SO post подробную информацию о том, как вставлять с помощью .NET Core.

Извлечение информации о манифестах выглядит аналогичным - просто используйте this.GetType().GetTypeInfo().Assembly.GetManifestResourceNames(), чтобы получить манифест из сборки, где выполняется код.

Я еще не понял, как сделать эквивалент Assembly.GetExecutingAssembly() в .NET Core! если кто-нибудь знает - сообщите мне, и я уточню этот ответ.

+4

Это сработало. ProjectName.Resources.Help.txt - это имя встроенного ресурса. – Ron

+2

Я рад помочь! Если вы чувствуете, что эта почта ответила на ваш вопрос, пожалуйста, не забудьте отметить это как принятый ответ. – Jay

+0

Полезно. Благодарю. –

-1

Возможно, вам нужно указать путь к вашему txt-файлу в параметре GetManifestResourceStream, или вы можете попробовать вставить файл txt в тот же каталог, что и ваш исполняемый файл. Надеюсь, это поможет!

35

У меня была аналогичная проблема, сначала проверьте, что файл включен в ваш проект, затем перейдите к свойствам и установите действие сборки этого файла в Embedded Resource. это сработало для меня.

+0

Это помогло мне! У меня было несколько ранее добавленных файлов, которые по умолчанию были встроены в ресурс, а затем те, которые я добавил позже, которые были установлены в «Нет». Visual Studio так раздражает время от времени. Хуже всего то, что во всех файлах XML для ресурсов нет настроек для действий сборки. Должно быть установлено действие сборки. –

+0

Не забудьте использовать пространство имен по умолчанию и путь к ресурсу. например, 'DefatultNameSpace.Infrastructure.Help.txt'. Пространство имен по умолчанию на странице свойств проекта и 'Инфраструктура' будет папкой, в которой находится файл –

+0

Это то, что я хотел, Cheers! – tabby

5

Просто предупреждение.

Я не смог получить доступ к своему файлу в качестве встроенного ресурса, хотя я указал, что он был, и хотя у него было свойство Build Action. Потратил много времени, ударяя головой. Я вложил файл кода csharp с .txt, добавленным к его имени (xxx.cs.txt). По каким-то причинам методы GetManifestResourceNames() и GetManifestResourceStream() не будут видеть файл с именем .cs.

Я переименовал его просто в xxx.txt, и все было в порядке.

Странно.

+0

Это слишком долгое время! Он будет внедрять его, если вы используете 'Resource', но не' Embedded Resource', что делает его еще более странным ... Удаление '.cs.' из имени заставляет его работать. Argh. – Matt

+0

Проблема не в том .cs. путь/сегмент в файлах распознается как файл C#, а скорее как CultureInfo. –

+1

Кажется, что с двойным расширением он вообще не работает. –

0

У меня была такая же проблема, благодаря Джей, я обнаружил, что в названии каталога были дефисы.

ProjectName.ResourceFolder.Sub-Directory становится ProjectName.ResourceFolder.Sub_Directory, когда вы ссылаетесь на поток ресурсов.

7

Вот причина моего нулевого значения.

http://adrianmejia.com/blog/2011/07/18/cs-getmanifestresourcestream-gotcha/

Метод GetManifestResourceStream всегда будет возвращает NULL, если ресурс «построен действие» свойство не установлено на «внедренный ресурс»

После установки этого свойства со всеми необходимыми файлами assembly.GetManifestResourceStream начинается возвращение поток corrent вместо NULL

+0

Еще раз спасибо. Это зафиксировало мою проблему месяц или два назад, тогда я забыл об этом и имел ту же проблему, и он исправил ее снова. – Rich

0

В моем случае проблема заключалась в том, что код, ищущий ресурс, был в другом проекте, что сам ресурс.

Доступ к ресурсам, находящимся в том же проекте, доступен только для кода. Я думал, что могу поместить все свои ресурсы в проект веб-страницы, но мне нужны изображения в почтовом проекте.

Надеюсь, это поможет кому-то в той же ситуации, какой я был.

Мне очень полезно звонить Assembly.GetExecutingAssembly().GetManifestResourceNames();.

Смежные вопросы