Що означає MissingManifestResourceException і як це виправити?


151

Ситуація:

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

Я отримую MissingManifestResourceExceptionтаке повідомлення:

Не вдалося знайти жодних ресурсів, відповідних зазначеній культурі чи нейтральній культурі. Переконайтесь, що "Servers.Resources.resources" було правильно вбудовано або пов'язано в збірку "RT.Servers" під час компіляції, або що всі необхідні супутникові збори є завантажуваними та повністю підписаними.

Я ніколи не бавлявся з культурою чи підписанням акторів, тому не знаю, що тут відбувається. Також це працює в іншому проекті, який використовує ту саму бібліотеку. Будь-які ідеї?


2
Це одне з найкорисніших винятків у .NET. Він спрацьовує щонайменше у трьох сценаріях, які не мають нічого спільного.
rr-

1
Вибачте, але це спосіб Microsoft: видаліть усе, а потім додайте ще раз . Працює для ресурсів, NUGET, посилань та рядків з'єднання. Інструментів дуже багато, але ви витратите час на необроблені файли у
незвичних

Відповіді:


238

Все, що мені потрібно було зробити, щоб виправити цю проблему, - це клацнути правою кнопкою миші Resources.resxфайл у Провіднику рішень та натиснути Запустити спеціальний інструмент . Це знову генерує автоматично створений Resources.Designer.csфайл.

Якщо файл .resx до проекту було додано вручну, властивість власного інструменту для цього файла має бути встановлено на "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". Я робив це вручну, але запуск користувальницького інструменту так само добре зробив би це.


9
Це врятувало мені багато часу!
Ерік

1
+1! У VS 2010 показана вище літеральна рядок ResourceManager автоматично оновлюється до значення простору імен за замовчуванням у властивостях проекту (вкладка Application), принаймні для WinForms.
TrueWill

2
Що робити, якщо у вас немає файлу resource.resx?
ashes999

@ ashes999: Ви шукали в папці "Властивості"? Ось де зазвичай це є принаймні для проектів C #.
RenniePet

я запустив ту саму проблему. Файл .resx був доданий до проекту вручну, властивість користувальницького інструменту файлу, який я встановив на "ResXFileCodeGenerator". пізніше .resx-файл. як я можу це зробити ....
Кавіта

37

Я щойно зіткнувся з цією проблемою сьогодні, і знайшов цю сторінку довідки та підтримки Microsoft, яка насправді вирішила проблему.

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

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

Потім я перемістив делегатів у область імен, отримав ту саму помилку. Нарешті я помістив делегатів у єдиний клас у цьому файлі, і помилка зникла, але я не хотів, щоб делегати в цьому класі чи просторі імен.

Тоді я натрапив на те посилання вище, де сказано

Щоб вирішити цю проблему, перемістіть усі інші визначення класів так, щоб вони з'явилися після визначення класу форми.

Я розміщував делегатів (які я б не вважав "визначеннями класів") внизу цього файлу, поза місцевим простором імен, і програма більше не отримувала MissingManifestResourceException. Яка дратівлива помилка. Але це здається більш надійним рішенням, ніж зміна автоматично створеного коду :)


Дякую за вашу відповідь. Це здається, що у вас була інша проблема, яка викликала той самий симптом. У мене в коді не було зайвих класів, насправді я навіть не мав форм. Я повинен відредагувати свою попередню відповідь, оскільки я виявив, що насправді не потрібно змінювати автоматично створений код. Я міг би просто запустити генератор коду, і він би зафіксував себе. Не маю уявлення, чому процес збирання не робив це автоматично.
Timwi

7
Я отримав помилку через додавання класу над класом форми у файл Form1.cs (як обговорювалося в розділі "Розв'язання" посиланням, яке ви надали). Дякую!
Метт Сміт

Та ж проблема; нічого іншого не працювало, тому я просто видалив рядок: this.Icon = ((System.Drawing.Icon) (resources.GetObject ("$ this.Icon"))); бо я не переймаюся іконою саме в цій формі :)
Gary Huckabone

Ось відповідь. Дякую.
Сертан Пекель

Якщо хтось плутався, у мене був клас під назвою "StringExtensions" перед бітом Form1cs "Form1", я перемістив його нижче Form1 у form1.cs замість вище, і він спрацював
Ma Dude,

31

Я зіткнувся з подібною проблемою, і хоча я знаю, що це не причина, з якою сталася ОП, я опублікую її тут, щоб, якщо хтось інший зіткнувся з цією проблемою, у майбутньому відповідь буде доступна.

Якщо ви додасте клас до класу дизайнера, ви отримаєте MissingManifestResourceExceptionвиняток під час виконання (відсутність помилки часу компіляції чи попередження), оскільки

Visual Studio вимагає, щоб дизайнери використовують перший клас у файлі.

Для (трохи) більше інформації дивіться цей пост .


12
Дякуємо, що опублікували цю "відповідь". Незважаючи на те, що це "поза темою" стосовно проблеми ОП, було гарною ідеєю опублікувати це тут. Пошуки MissingManifestResourceException привели мене до цієї теми, і ваша відповідь виявилася точкою моєї проблеми.
RenniePet

16

У мене була така ж проблема, але використання команди " Custom Custom Tool", як запропонував Timwi , не допомогло в моєму випадку.

Однак це призвело мене в правильному напрямку, тому що я опинився в властивостях цього .resx файлу. Тут я помітив різницю в іншому .resx- файлі, який не викликав проблем.

У моєму випадку мені довелося змінити властивість "Build Action" з "Resource" на "Embedded Resource".

Моя найкраща здогадка з тієї причини полягає в тому, що я мав .resx в бібліотеці, яку використовували в іншому додатку. У мого додатку не було власного файлу .resx , тому довелося використовувати той з бібліотеки - який доступний лише тоді, коли він вбудований у бібліотеку, а не "окремо стоїть".


2
+1 дякую, я ще раз перевірив свої файли ресурсів, які також знаходяться в окремій бібліотеці, на яку посилаються інші програми. У мене було створено Дію збірки на Вміст, і після зміни її на Вбудований ресурс усе працювало добре. Дурний нагляд
Шань Плорд

1
Дякую! Це працювало для мене, коли у мене були текстові файли, що містять вміст або для тестування, або для деяких правил відображення бізнесу. Перехід від вмісту до вбудованого ресурсу вирішив проблему.
С. Баггі

12

Коли я запускаю аналогічну проблему, у Vs 2012 виявилося, що властивість «Спеціального простору імен» у файлі resx була помилковою (у моєму випадку, насправді, вона була не налаштована, тому згенерований код викреслює цей виняток під час виконання) . Мій остаточний набір властивостей для файлу resx був приблизно таким:

  • Дія побудови: вбудований ресурс
  • Копіювати у вихідний каталог: не копіюйте
  • Спеціальний інструмент: ResXFileCodeGenerator
  • Простір імен користувальницьких інструментів: My.Project.S.Proper.Npace

3

Також дивіться: 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 " . "


Приблизно через вісім годин налагодження цієї проблеми та буквального проходу через кожен github, SO та відповіді Google, це відповідь, яка вирішила мою проблему ... fwiw, моя проблема почала відбуватися після переходу з .Net 3.5 на 4.7.2.
Невіл

3

Я зіткнувся з іншою причиною цієї проблеми, яка не стосувалася файлів resx. У мене була бібліотека класів, де AssemblyInfo.cs містила наступне:

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

Асамблея не містила жодного коду, теми чи словника WPF. Я позбувся винятку, видаливши атрибут ThemeInfo.

Я не отримав лише фактичного винятку

Перший випадковий виняток типу "System.Resources.MissingManifestResourceException".

Переглядаючи деталі винятків, система запитувала ресурси MyAssembly.g.resres

Сподіваюся, що це може допомогти комусь іншому.


2
Дякую за це! Саме виправлення мені було потрібно! Відбувається, коли ви випадково створюєте проект ViewModel як бібліотеку Control.
Ендрю Ханлон

Дякую. Це зафіксувало це для мене.
Джамлек

2

Не впевнений, що це допоможе людям, але цей працював на мене:

Тож у мене було те, що я отримував таке повідомлення:

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

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

Що я зробив, щоб виправити проблему, було встановити Модифікатор доступу на вкладці Проект-> Властивості-> Ресурси з "Внутрішній" (доступний лише в межах однієї бібліотеки класів) на "Публічний" (доступний з іншої бібліотеки класів)

Тоді біжіть і voilà, більше помилок для мене ...


2

Рішення, яке дав BlaM, працювало і для мене.

Я користувач VS 2013 року. Провівши багато виправлень, але не пощастило, я спробував це:

  1. Клацніть правою кнопкою миші файл ресурсу, один за одним, у випадку кількох файлів.
  2. Переконайтеся, що для властивості "Дія побудови" встановлено значення "Вбудований ресурс".

Це воно! :)


Підтвердження цього. У мене є робочий проект, але потрібно було підтримувати збірки ресурсів окремо, тому спробував перейти з "Вбудованого ресурсу" на просто "Ресурс" і в результаті отримав MissingResourceManifestException.
Моска Пт

2

У мене був той самий випуск, але в моєму випадку я розміщую клас в usercontrol, який пов'язаний з usercontrol, як це

Public Class MyUserControlObject

end Class

Public Class MyUserCOntrol

end Class

Рішенням було перенести на MyUserControlObjectкінець класу Usercontrol, як це

Public Class MyUserCOntrol

end Class

Public Class MyUserControlObject

end Class

Я сподіваюся, що це допомагає


Поговоримо про опис хитрої помилки ... До CS-файлу основної форми я додав допоміжний клас. Ніколи б я не здогадувався, що повідомлення про помилку буде посилатися на це. Дякую!
Адам Льюїс

1

Я отримав помилку MissingManifestResourceException після перенесення свого проекту з VS2005 на VS2010. У мене не було визначено інших класів у файлі, який містить мій клас Form. І у мене також було встановлено правильно своє ім'я файлу resx Resource. Не працювало.

Тому я видалив файли resx та відновив їх. Все добре зараз.


1

Нещодавно зіткнувся з тією ж проблемою, трохи поборовся, знайшов цю тему, але відповіді для мене не були правильними.

Моє питання полягає в тому , що коли я витягував головне вікно з мого проекту WPF (це не головне вікно), я забув зняти StartupUriз App.xaml. Я припускаю , що це виняток може статися , якщо є помилка в StartupUri, так що в разі , якщо хто -то бореться з цим - перевірити StartupUriпісля прибуття App.xaml.


1

Нещодавно натрапивши на це питання, у моєму випадку я зробив кілька речей:

  1. Переконайтесь, що простори імен узгоджуються у файлі Designer.cs файла resx

  2. Переконайтеся, що для простору імен у збірці (клацніть правою кнопкою миші проект та виберіть "Властивості") встановлено однакове для простору імен, у якому знаходиться файл ресурсів.

Як тільки я зробив крок 2, виняток пішов.


1

У мене була ця проблема, коли я додав ще один клас у файл безпосередньо перед класом, який походить із Form. Додавання після вирішення проблеми.


1

Також така ж помилка може виникнути, коли ви кладете новий клас у вихідний код класу створеної дизайнером форми.

Цей новий клас може бути видалений та поміщений у інший файл CS.

(Принаймні, в моєму випадку це була проблема ...)


0

Оскільки я попередньо збираю свій веб-додаток (використовуючи функцію публікації VS2012). Я отримував помилку вище. Я спробував усі пропозиції, але дивно змінивши "Зробити дію" на "Вміст", зробив трюк!


0

У моєму випадку у мене є веб-api з ресурсами, і я створюю з цього пакунок. Коли я використовую цей нутіг в інших проектах, я розумію, що коли я запитую api з ресурсами, я отримую MissingManifestResourceExceptionпісля невеликого повторного дослідження, я дізнаюся, що логічний пакувальник не запакує ресурси автоматично. Якщо ви хочете використовувати файли ресурсів, вам це потрібно зробити вручну. Тому вам потрібно додати нижче рядки до вашого .nuspec-файлу: (Відвідайте https://github.com/NuGet/Home/isissue/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 ви використовуєте.


0

У мене був нещодавно створений проект F #. Рішення полягало в тому, щоб зняти прапорець "Використовувати стандартні імена ресурсів" у властивостях проекту -> Застосування -> Ресурси / Вкажіть, як керуватимуть ресурсами програми. Якщо ви не бачите прапорець, то оновіть свою Visual Studio! У мене встановлено 15.6.7. У 15.3.2 цього прапорця немає.


0

Просто згадати. Якщо ви використовуєте константу або буквально, переконайтеся, що вона посилається на ресурс форми ProjectName.Resources, а не cpntain Resources.resx.

Це може врятувати вас годину чи дві.


0

Я зіткнувся з цією проблемою з керованим проектом C ++ на основі WinForms після перейменування глобального простору імен (не вручну, а за допомогою інструмента Перейменування VS2017).

Рішення просте, але ніде не згадується.

Ви повинні змінити RootNamespaceзапис у vcxproj-файл, щоб він відповідав простору імен C ++.


0

У моєму випадку це була помилка друку у Xaml вікна, відкритого з форми Winforms:

Неправильно: <Image Source="/Resources/WorkGreen.gif"/>

Правильно: <Image Source="../Resources/WorkGreen.gif"/> це може комусь допомогти


-3

На сторінці підтримки Microsoft :

Ця проблема виникає, якщо ви використовуєте локалізований ресурс, який існує у створеній вами супутниковій збірці, використовуючи файл .resources, який має невідповідне ім’я файлу. Ця проблема зазвичай виникає, якщо ви вручну створили супутникову збірку.

Щоб вирішити цю проблему, вкажіть ім’я файлу .resources під час запуску Resgen.exe. Поки ви вказуєте ім'я файлу .resources, переконайтеся, що ім'я файлу починається з імені простору імен вашої програми. Наприклад, запустіть таку команду в командному рядку Microsoft. Visual Studio .NET, щоб створити .resources файл, який містить ім'я простору імен вашої програми на початку імені файлу:

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

1
Дякую за вашу відповідь, але я не знаю, що таке ResGen.exe, я ніколи не користувався ним, і відверто кажучи, не хочу його використовувати, тому що не намагаюся використовувати щось фантазійне. Невже має бути спосіб виправити це за допомогою Visual Studio? Наприклад, оскільки ви говорите, що ресурс "локалізований", як я можу оголосити ресурс не локалізованим? Знову дякую.
Тімві
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.