MissingManifestResourceException для EmbeddedResouce в Silverlight - PullRequest
1 голос
/ 20 сентября 2011

Я пишу игры для Silverlight, используя движки Silverlight на основе XNA.У меня есть предыдущая игра, где у меня есть файлы (MP3 и текстовые файлы) с Build Action, установленным на Embedded Resource, и в моем решении нет файла *.resx.

Игра работает нормально;Вы можете увидеть рабочую версию здесь .

С другой стороны, мой текущий проект не позволяет этого.Когда я пытаюсь сделать файлы Embedded Resource s, я получаю MissingManifestResourceException , брошенный в мой конструктор основного экземпляра UserControl, который запускает мое приложение.Сообщение об ошибке:

Не удалось найти ресурсы, подходящие для указанной культуры или нейтральной культуры.Убедитесь, что «DeenGames.Colosseum.Content.Audio.2.mp3.resources» был правильно встроен или связан со сборкой «DeenGames.Colosseum» во время компиляции или что все требуемые сателлитные сборки являются загружаемыми и полностью подписаны.

Я очень, очень, очень озадачен.Установка любого элемента Build Action в Embedded Resource, будь то MP3, текст или изображение, вызывает это исключение.

Как, черт возьми, я могу это исправить (или отладить)?Я на 99% уверен, что не нужен .resx файл, потому что мои предыдущие проекты не имеют его.

Там есть эта прекрасная страница MSDN , котораяуверяет мир, что:

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

Но есть известное решение, использующее Assembly.GetExecutingAssembly().GetManifestResourceNames().В моем случае это не показывает ресурс, если это просто Resource;если это Embedded Resource, я вижу имя файла с разделенным точками пространством имен (как и ожидалось).

Скачайте и убедитесь сами в простом рабочем примере здесь .Он имеет два встроенных файла (.2dg и .map) и компилирует / запускает без каких-либо исключений ИЛИ файл resx.

Вы также можете скачать неработающий пример здесь .Замените FlatRedBall.dll на RadiantWrench.dll и посмотрите, как работает рабочий пример.(Используйте ScreenController.ShowScreen и удалите весь код FRB.)

1 Ответ

0 голосов
/ 30 сентября 2011

Встроенный ресурс - это технология WinForms, которая устарела во время выполнения Silverlight. Вместо этого следует использовать действие построения Resource или Content .

Когда вы устанавливаете элемент в Встроенный ресурс , Silverlight ожидает, что это будет файл .resx, потому что именно это происходит внутри файла .csproj или .vbproj при создании .resx и добавлении ресурсов в это (файл помечен как Embedded Resource для MSBuild, а его ресурсы - это просто None внутри <ItemGroup/>, которые обнаруживаются ResXGenerator во время выполнения на основе относительной папки URI «Ресурсы» ). Если это не так, он удаляет его или устанавливает его как Content . Вы можете просмотреть Microsoft.Silverlight.Common.targets (обычно в папке C: \ Program Files (x86) \ MSBuild \ Microsoft \ Silverlight \ v4.0), чтобы увидеть, как он изменяет элементы, помеченные как * 1019. * Embedded Resource - настройка содержимого, настройка none или настройка файла .resx.

Если вы хотите просто запросить, какие ресурсы у вас есть в проекте, вы можете попробовать этот несколько громоздкий подход: Перечисление встроенных ресурсов


ОБНОВЛЕНИЕ: При рассмотрении вашего проекта на самом деле не используется встроенный ресурс, как WinForms использует этот тип действия сборки или даже .resx, скажем так. Он использует функцию из ToolsSilverlight.dll , которая называется EmbeddedResourceFileReader.ReadFile. Код для этого:

    private static string ReadFile(string fileName, Assembly currentAssembly)
    {
        string text = EmbeddedResourceHelper.CheckAndSanitizePath(fileName);
        string result = "";
        using (Stream manifestResourceStream = currentAssembly.GetManifestResourceStream(text))
        {
            if (manifestResourceStream == null)
            {
                throw new ArgumentException("Couldn't open " + fileName + ". Make sure the file exists in that directory, and has Build Action set to Embedded Resource.");
            }
            using (StreamReader streamReader = new StreamReader(manifestResourceStream))
            {
                result = streamReader.ReadToEnd();
            }
        }
        return result;
    }

Ваш файл .csproject перечисляет ваши файлы как:

<ItemGroup>
    <EmbeddedResource Include="Content\Qadar.2dg" />
    <EmbeddedResource Include="Content\Maps\main.map" />
    <None Include="Properties\AppManifest.xml" />
</ItemGroup>

Все, что это делает, встраивается, как указано выше в Microsoft.Silverlight.Common.targets , ваши файлы в качестве общих ресурсов (на верхнем уровне, а не в списке других фактических ресурсов) и находит способ прочитать их. Вы можете декомпилировать свою DLL с помощью ILSpy, чтобы проверить, что это действительно общие ресурсы в папке Resources.

Так как вы можете сделать это в вашем новом проекте? Скопируйте точный метод, который вы использовали в своем первом - добавьте ToolsSilverlight.dll, перечислите ваши элементы как встроенный ресурс и вызовите их, используя EmbeddedResourceFileReader.ReadFile. Вы также можете убедиться, что ваша структура .csproj file <ItemGroup/> аналогична оригинальной. Не уверен, нужен ли <None Include="Properties\AppManifest.xml"/> для EmbeddedResourceFileReader, но это может быть.

...