Что означает MissingManifestResourceException и как это исправить? - PullRequest
140 голосов
/ 25 августа 2009

Ситуация:

  • У меня есть библиотека классов, которая называется RT.Servers и содержит несколько ресурсов (типа byte[], но я не считаю это важным)
  • В той же библиотеке классов есть метод, который возвращает один из этих ресурсов
  • У меня есть простая программа (со ссылкой на эту библиотеку), которая вызывает только этот единственный метод

Я получаю MissingManifestResourceException со следующим сообщением:

Не удалось найти ресурсы подходит для указанной культуры или нейтральная культура. Удостовериться "Servers.Resources.resources" был правильно встроен или связан с сборка "RT.Servers" во время компиляции, или что все спутниковые сборки Требуются загружаемые и полностью подписан.

Я никогда не играл с культурами или с подписанием сборок, поэтому я не знаю, что здесь происходит. Кроме того, это работает в другом проекте, который использует ту же библиотеку. Есть идеи?

Ответы [ 19 ]

224 голосов
/ 25 августа 2009

Все, что мне нужно было сделать, чтобы решить эту проблему, это щелкнуть правой кнопкой мыши файл Resources.resx в обозревателе решений и выбрать Запустить пользовательский инструмент . Это автоматически создает автоматически сгенерированный файл Resources.Designer.cs.

Если файл .resx был добавлен в проект вручную, то для свойства Custom Tool этого файла должно быть установлено значение «ResXFileCodeGenerator».

Проблема связана с несоответствием пространств имен, которое возникает при изменении «пространства имен по умолчанию» сборки в настройках проекта. (Я изменил его с (ранее) "Servers" на (сейчас) "RT.Servers".)

В автоматически сгенерированном коде в Resources.Designer.cs есть следующий код:

internal static global::System.Resources.ResourceManager ResourceManager {
    get {
        if (object.ReferenceEquals(resourceMan, null)) {
            global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Servers.Resources", typeof(Resources).Assembly);
            resourceMan = temp;
        }
        return resourceMan;
    }
}

Буквенная строка "Servers.Resources" должна быть изменена на "RT.Servers.Resources". Я сделал это вручную, но запуск собственного инструмента был бы одинаково хорош.

33 голосов
/ 02 сентября 2009

Я только что столкнулся с этой проблемой сегодня, и нашел эту страницу справки и поддержки Microsoft , которая действительно обошла проблему.

У меня была пара делегатов вверху моего файла в глобальном пространстве имен, и внезапно я получил MissingManifestResourceException при запуске программы, в этой строке:

this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));

Затем я переместил делегатов в пространство имен, получил ту же ошибку. Наконец, я поместил делегатов в единственный класс в этом файле, и ошибка исчезла, но я не хотел, чтобы делегаты в этом классе или пространстве имен.

Потом я наткнулся на ссылку выше, где говорилось

Чтобы решить эту проблему, переместите все другие определения классов так, чтобы они появлялись после определения класса формы.

Я поместил делегатов (которые я бы не рассматривал «определения классов») внизу этого файла, вне локального пространства имен, и программа больше не получила MissingManifestResourceException. Какая раздражающая ошибка. Но это кажется более надежным решением, чем изменение автоматически сгенерированного кода:)

26 голосов
/ 01 декабря 2010

Я столкнулся с подобной проблемой, и, хотя я знаю, что это не является причиной OP, я опубликую ее здесь, так что если кто-то еще столкнется с этой проблемой в будущем, ответ будет доступен.

Если вы добавите класс перед классом конструктора, вы получите исключение MissingManifestResourceException во время выполнения (без ошибок или предупреждений во время компиляции), поскольку

Visual Studio требует, чтобы дизайнеры использовали первый класс в файле.

Для (немного) дополнительной информации см. этот пост .

15 голосов
/ 08 сентября 2010

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

Однако это привело меня кправильное направление, потому что я попал в Свойства файла .resx .Здесь я заметил разницу с другим файлом .resx , который не вызывал проблем.

В моем случае мне пришлось изменить свойство «Build Action» с «Resource» на «Embedded Resource».

Моя лучшая догадка по той причине, что у меня был .resx в библиотеке, которая использовалась из другого приложения.У моего приложения не было своего собственного .resx файла, поэтому ему пришлось использовать файл из библиотеки, который доступен только в том случае, если он встроен в библиотеку, а не «автономен».

11 голосов
/ 22 августа 2014

Когда я запускал аналогичную проблему, в Vs 2012 оказалось, что свойство «Пространство имен пользовательских инструментов» файла resx неверно (в моем случае, на самом деле, оно не было установлено, поэтому сгенерированный код выдает это исключение во время выполнения). Мой последний набор свойств для файла resx был примерно таким:

  • Действие построения: Встроенный ресурс
  • Копировать в выходной каталог: Не копировать
  • Пользовательский инструмент: ResXFileCodeGenerator
  • Пространство имен пользовательских инструментов: My.Project.S.Proper.Namespace
3 голосов
/ 18 февраля 2015

Я столкнулся с другой причиной этой проблемы, которая не была связана с файлами resx. У меня была библиотека классов, где AssemblyInfo.cs содержал следующее:

[assembly: ThemeInfo(
ResourceDictionaryLocation.SourceAssembly,
ResourceDictionaryLocation.SourceAssembly)]

Сборка не содержала кодов WPF, тем или словарей ресурсов. Я избавился от исключения, удалив атрибут ThemeInfo.

Я не получил фактическое исключение, только

Первое случайное исключение типа 'System.Resources.MissingManifestResourceException'.

Просмотр сведений об исключении, система запрашивала MyAssembly.g.resources

Надеюсь, это может помочь кому-то еще.

2 голосов
/ 19 декабря 2012

Также см .: MissingManifestResourceException при запуске тестов после сборки с MSBuild (.mresource имеет путь в манифесте)

Я повторяю здесь ответ только для полноты:

Похоже, добавление LogicalName в файл проекта исправляет это:

<LogicalName>$(RootNamespace).Properties.Resources.resources</LogicalName> 

т.е. поэтому встроенная запись ресурса в файле проекта выглядит следующим образом:

<ItemGroup>
  <EmbeddedResource Include="Properties\Resources.resx">
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    <LogicalName>$(RootNamespace).Properties.Resources.resources</LogicalName> 
  </EmbeddedResource>
</ItemGroup>

Это подробно описано в: http://blogs.msdn.com/b/msbuild/archive/2007/10/19/manifest-resource-names-changed-for-resources-files.aspx

Обратите внимание, что мы используем файл .resx, но ошибка по-прежнему возникает.

Обновление: проблема с ресурсами (включая XAML), по-видимому, связана с путями вывода и использованием прямой или обратной косой черты, как подробно описано в: Почему изменение выходных каталогов проекта вызывает: исключение IOException "Невозможно найти ресурс app.xaml". "

2 голосов
/ 30 января 2014

Не уверен, что это поможет людям, но этот работал для меня:

Итак, у меня возникла проблема: я получал следующее сообщение:

Не удалось найти ресурсы, подходящие для указанной культуры или нейтральной культуры. Убедитесь, что «My.Resources.Resources.resources» был правильно встроен или связан со сборкой «X» во время компиляции, или что все требуемые спутниковые сборки загружаемы и полностью подписаны »

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

Что я сделал, чтобы решить эту проблему, так это установить для Модификатора доступа на вкладке Проект-> Свойства-> Ресурсы значение «Внутреннее» (доступное только в той же библиотеке классов), как «Публичное» (доступное из другой библиотеки классов)

Тогда беги и вуаля, больше нет ошибок для меня ...

2 голосов
/ 12 августа 2016

У меня была та же проблема, но в моем случае я помещаю класс в usercontrol, который связан с usercontrol следующим образом

Public Class MyUserControlObject

end Class

Public Class MyUserCOntrol

end Class

Решением было переместить MyUserControlObject в конец класса Usercontrol, как это

Public Class MyUserCOntrol

end Class

Public Class MyUserControlObject

end Class

Надеюсь, это поможет

2 голосов
/ 10 августа 2016

Решение, данное BlaM, сработало и для меня.

Я - пользователь VS 2013. Пройдя через множество исправлений, но не повезло, я попробовал это:

  1. Щелкните правой кнопкой мыши файл ресурсов, один за другим, в случае нескольких файлов.
  2. Убедитесь, что для свойства "Действие сборки" установлено значение "Встроенный ресурс".

Вот и все! :)

...