Не удается загрузить ресурс манифеста с помощью GetManifestResourceStream()
Я создал пользовательский раздел конфигурации, используя XSD. Чтобы проанализировать файл конфигурации, который следует за этой новой схемой, я загружаю ресурс (мой файл.xsd) с этим:
public partial class MonitoringConfiguration
{
public const string ConfigXsd = "MonitoringAPI.Configuration.MonitoringConfiguration.xsd";
public const string ConfigSchema = "urn:MonitoringConfiguration-1.0";
private static XmlSchemaSet xmlSchemaSet;
static MonitoringConfiguration()
{
xmlSchemaSet = new XmlSchemaSet();
Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);
XmlReader schemaReader = XmlReader.Create(xsdStream);
xmlSchemaSet.Add(ConfigSchema, schemaReader);
}
}
Кстати, мой ресурс: MonitoringConfiguration.xsd. И пространство имен другого частичного класса (который представляет код позади файла.xsd) MonitoringAPI.Configuration
,
Проблема находится здесь:
Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);
Значение xsdStream равно нулю, поэтому я думаю, что ресурс не найден! Но почему?
Спасибо
8 ответов
Название ресурса всегда:
<Base namespace>.<RelativePathInProject>.<FileName>
Поэтому, если ваш ресурс находится в "Resources/Xsd/", а пространство имен вашего проекта по умолчанию - "MonitoringAPI.Configuration", имя ресурса будет следующим:
"MonitoringAPI.Configuration.Resources.Xsd.MonitoringConfiguration.xsd"
Также убедитесь, что для действия сборки для вашего ресурса установлено значение "Встроенный ресурс".
Простой и правильный способ получить фактическое имя вашего встроенного ресурса:
string[] resourceNames =
Assembly.GetExecutingAssembly().GetManifestResourceNames();
Затем просто проверьте массив resourceNames, и вы точно будете знать, что передать методу GetManifestResourceStream.
В моем случае,
Когда вы пытаетесь получить доступ к файлу через GetManifestResourceStream()
, Вы получите ошибку из-за неверного пути к файлу, и поток будет нулевым.
Решение:
Щелкните правой кнопкой мыши файл, который вы добавили в решение, и выберите Свойства.
Выберите Build Action
как Embedded Resource
, (Вместо Content
- по умолчанию)
По умолчанию Visual Studio не встраивает xsd-файл, поэтому вы должны убедиться, что свойство "Build Action" для xsd-файла установлено в "Embedded Resource", чтобы оно работало.
Просто добавьте свои ресурсы в form1.resx -> добавить существующие элементы
дважды щелкните по ресурсам, которые вы добавили в папке Resources.go в свойствах, и выберите "Встроенные ресурсы" вместо "нет".
Затем попробуйте отладить строку:
string[] resourceNames=Assembly.GetExecutingAssembly().GetManifestResourceNames();
проверьте, что ресурсы, которые вы добавили, находятся в массиве. затем скопируйте имя ресурса именно из этого массива и попробуйте вставить имя в ваш код.. он работает отлично!!
Вы можете получить поток ресурсов, передав имена ресурсов, как показано ниже...
Получить имя ресурса, например.
Assembly objAssembly = Assembly.GetExecutingAssembly ();
string [] strResourceNames = objAssembly.GetManifestResourceNames ();
Передать имена ресурсов в...
Stream strm = objAssembly.GetManifestResourceStream (strResourceNames);
Теперь у вас есть Stream, вы можете делать все, что хотите...
В моем случае это было что-то совершенно другое:
Мое приложение UWP правильно скомпилировано в конфигурации Debug и Release, но GetManifestResourceStream вернул конфигурацию Release только для Null.
Проблема заключалась в том, что в файле конфигурации сборки UWP (и только там) был включен параметр "Компилировать с цепочкой инструментов.NET Native". После отключения GetManifestResourceStream работал как положено.
У меня была проблема, когда я встраивал целую кучу файлов.xsd в разные сборки; все работало (GetManifestResourceNames возвращал файлы, которые я ожидал увидеть), кроме одного. Тот, который не был назван:
Something.LA.xsd
Я не имел дело с конкретными культурами, и бит.LA в конце имени файла выбирался компилятором, так как этот файл был для культуры LA - имя файла в манифесте входило как Something.xsd (под культурой ЛА) - следовательно, я не смог найти его (он оказался в сателлитной сборке). Я избежал этой проблемы, переименовав файл - возможно, можно явно указать культуру данного встроенного ресурса.
На самом деле, быстрый Google показывает: как я могу предотвратить настройку встроенного файла ресурсов на основе его имени файла
Согласно этому ответу, вы должны заниматься хакерскими делами - так что, возможно, переименование файла не так уж и плохо:)