Что означает MissingManifestResourceException и как его исправить?

Ситуация:

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

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

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

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

Ответ 1

Все, что мне нужно было сделать, чтобы исправить эту проблему, - это щелкнуть правой кнопкой мыши файл 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". Я сделал это вручную, но выполнение специального инструмента было бы так же хорошо сделано.

Ответ 2

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

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

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

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

Затем я наткнулся на эту ссылку выше, в которой говорилось

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

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

Ответ 3

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

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

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

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

Ответ 4

У меня была та же проблема, но с помощью команды Run Custom Tool в предложенной Timwi, в моем случае это не помогло.

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

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

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

Ответ 5

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

  • Действие сборки: Встроенный ресурс
  • Скопировать в выходной каталог: Не копировать
  • Пользовательский инструмент: ResXFileCodeGenerator
  • Пользовательское пространство имен: My.Project.S.Proper.Namespace

Ответ 6

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

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

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

<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" . "

Ответ 7

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

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

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

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

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

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

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

Ответ 8

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

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

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

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

Что я сделал, чтобы исправить проблему, было установить модификатор доступа на вкладке Project- > Properties- > Resources из "Internal" (доступный только в пределах той же библиотеки классов) до "Public" (доступный из другой библиотеки классов)

Затем запустите и voilà, для меня больше нет ошибок...

Ответ 9

Решение, данное BlaM, тоже помогло мне.

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

  • Щелкните правой кнопкой мыши файл ресурсов, один за другим, в случае нескольких файлов.
  • Убедитесь, что для свойства Build Action установлено значение "Embedded Resource".

Что это!:)

Ответ 10

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

Public Class MyUserControlObject

end Class

Public Class MyUserCOntrol

end Class

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

Public Class MyUserCOntrol

end Class

Public Class MyUserControlObject

end Class

Я надеюсь, что это поможет

Ответ 11

Я получал ошибку MissingManifestResourceException после того, как портировал свой проект с VS2005 на VS2010. У меня не было других классов, определенных в файле, который содержит мой класс Form. И у меня также было правильно задано имя файла ресурсов resx. Не работает.

Итак, я удалил файлы resx и восстановил их. Теперь все хорошо.

Ответ 12

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

Моя проблема заключалась в том, что когда я удалил главное окно из моего проекта WPF (у него нет главного окна), я забыл удалить StartupUri из App.xaml. Я предполагаю, что это исключение может произойти, если у вас есть ошибка в StartupUri, поэтому в случае, если кто-то борется с этим - проверьте StartupUri на App.xaml.

Ответ 13

Недавно наткнулся на эту проблему, в моем случае я сделал несколько вещей:

  1. Убедитесь, что пространства имен согласованы в файле Designer.cs файла resx

  2. Убедитесь, что пространство имен по умолчанию для сборки (щелкните правой кнопкой мыши по проекту и выберите "Свойства") установлено равным пространству имен, в котором находится файл ресурсов.

Как только я сделал шаг 2, исключение ушло.

Ответ 14

Потому что я предварительно компилирую мое веб-приложение (используя функцию публикации VS2012). Я получил ошибку выше. Я попробовал все предложения, но странное изменение "Build Action" на "Content" сделало трюк!

Ответ 15

В моем случае у меня есть веб-API с ресурсами, и я создаю пакет Nuget из этого. Когда я использую этот nuget в других проектах, я понимаю, что когда я запрашиваю API с ресурсами, я получаю MissingManifestResourceException после небольшого повторного поиска, и я узнаю, что упаковщик nuget не упаковывает ресурсы автоматически. Если вы хотите использовать файлы ресурсов, вы должны сделать это вручную. Поэтому вам нужно добавить следующие строки в ваш файл .nuspec: (Посетите https://github.com/NuGet/Home/issues/1482).

<package> 
    <metadata>
    </metadata>
    <files>
        <file src="bin\Debug\en\MyAssembly.resource.dll" target="lib\net40\en\MyAssembly.resource.dll" />
        <file src="bin\Debug\es\MyAssembly.resource.dll" target="lib\net40\es\MyAssembly.resource.dll" />
    </files>
</package>

Но, прежде чем добавлять файлы, вам необходимо убедиться, какую версию .net вы используете.

Ответ 16

У меня был недавно созданный проект F #. Решением было снять флажок "Использовать стандартные имена ресурсов" в свойствах проекта → Приложение → Ресурсы/Указать, как будут управляться ресурсы приложения. Если вы не видите флажок, обновите Visual Studio! У меня установлена 15.6.7. В 15.3.2 этого флажка нет.

Ответ 17

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

Ответ 18

Просто чтобы упомянуть. Если вы используете константу или литерал, убедитесь, что они ссылаются на ресурс в форме ProjectName.Resources и не содержат cpntain Resources.resx.

Это может сэкономить вам час или два.

Ответ 19

Я столкнулся с этой проблемой в управляемом проекте C++ на основе WinForms после переименования глобального пространства имен (не вручную, а с помощью инструмента переименования VS2017).

Решение простое, но нигде не упоминается.

Вы должны изменить запись RootNamespace в файле vcxproj, чтобы она соответствовала пространству имен C++.

Ответ 20

От страница поддержки Microsoft:

Эта проблема возникает, если вы используете локализованный ресурс, который существует в сборке спутников, созданный с помощью файла .resources, который имеет неправильное имя файла. Эта проблема обычно возникает, если вы вручную создаете спутниковую сборку.

Чтобы обойти эту проблему, укажите имя файла .resources при запуске Resgen.exe. Пока вы указываете имя файла .resources, убедитесь, что имя файла начинается с имени пространства имен вашего приложения. Например, запустите следующую команду в командной строке Microsoft Visual Studio.NET, чтобы создать файл .resources, который имеет имя пространства имен вашего приложения в начале имени файла:

Resgen strings.CultureIdentifier.resx 
MyApp.strings.CultureIdentifier.resources