"Не удалось загрузить файл или сборку System.Drawing или одну из его зависимостей". Ошибка на .Net 2.0, VS2010 и Windows 8
Я получаю FileNotFoundException в проекте приложения Windows Forms со следующим сообщением:
Could not load file or assembly 'System.Drawing, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
The system cannot find the file specified.
Чтобы воспроизвести проблему:
- Выберите "Создать", "Проект", выберите .Net Framework 2.0 в качестве цели и выберите "Приложение Windows Forms" в качестве типа проекта.
- В свойствах формы, созданной по умолчанию, выберите значение свойства Icon. Будет выполнен любой файл .ico. Это вложит файл в файл resx.
- Скомпилируйте и запустите приложение.
Когда я это делаю, программа останавливается в строке this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
со следующим исключением:
System.IO.FileNotFoundException was unhandled
Message=Could not load file or assembly 'System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Source=mscorlib
FileName=System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Я получаю это на Visual Studio 2010 SP1, недавно установленном в Windows 8 Developer Preview. Если я изменю свойства проекта для таргетинга .Net Framework 4, ошибка исчезнет.
В файле Form1.resx я вижу, что версия сборки System.Drawing явно указана как 2.0:
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
Любые идеи?
Ответы
Ответ 1
Я нашел возможное решение, попробуйте следующее:
Откройте файл resx в конструкторе и настройте accessmodifier из общедоступного без генерации кода.
Изменить: есть обходной путь, но очень раздражает, хотя.
- Откройте форму в конструкторе и сделайте необходимые изменения графического интерфейса. Закрыть дизайнер и сохранить
- Скомпилировать проект и получить ошибку компиляции RESX (только формы с Imagelist должны иметь эту проблему)
- Дважды щелкните по ошибке компиляции resx, чтобы открыть файл resx.
- Перейдите в начало imagestream.
- Отредактируйте верхнюю строку потока изображений:
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
К
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
- Закрыть и сохранить файл resx и перекомпилировать.
** ПРИМЕЧАНИЕ. Единственное отличие - это символы в конце "j00LjAuMC4w" на "j0yLjAuMC4w"
Это нужно сделать КАЖДЫЙ РАЗ, вы открываете форму в режиме конструктора.
Microsoft заявляет, что собирается исправить ее в следующей версии VS...
Источник: http://connect.microsoft.com/VisualStudio/feedback/details/532584/error-when-compiling-resx-file-seems-related-to-beta2-bug-5252020
Ответ 2
Это ошибка. Я тоже это видел. Это происходит потому, что ваш файл .resx указывает на 4.0.0.0 версию System.Drawing, где его не существует. Чтобы решить эту проблему, я обычно редактирую .resx в блокноте для изменения 4.0.0.0 до 2.0.0.0. Ошибка указана в следующих точных шагах, которые вы наметили.
Ответ 3
Эта проблема может возникнуть, если .net 4.5 preview resgen используется для создания файлов ресурсов.
У меня такая же проблема на моем ноутбуке (Windows 7, VS2010 Premium, VS11 Developer Preview).
У меня возникла проблема с проектом простых форм, когда я говорю "localizable = true" в форме. В моем случае нет данных изображения. Проект имеет значение .net 3.5
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.SuspendLayout();
//
// Form1
//
resources.ApplyResources(this, "$this"); //exception Could not load file or assembly 'System.Drawing, Version=4.0.0.0,
Если я затем скопирую этот проект на другой компьютер (Windows 7, VS2010 Premium) и попытаюсь его отладить, ошибка останется.
Ошибка уходит, если я очищаю решение (а не проект) (или удаляю bin/obj вручную)
Если я затем скопирую это решение обратно на свой ноутбук, ошибка исчезнет, но я не могу увидеть форму снова в представлении дизайна 'Error message: at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.EnsureDocument(IDesignerSerializationManager manager)'
Причиной всего этого является версия .net в файлах *.Designer.cs.
- Версия выполнения: 4.0.30319.239 на компьютере, где он работает,
- Версия Runtime: 4.0.30319.17020 на ноутбуке, где я получаю исключение.
Может ли кто-нибудь сказать мне, где я могу настроить, какая версия resgen используется при работе с проектами .net 3.5?
Ответ 4
У меня была эта проблема, и мне показалось, что это странно связано с .Net 4.5 beta. Удаление этого и переустановка .Net 4.0 заставила проблему уйти. Не уверен, есть ли способ иметь .Net 4.5 beta и использовать ресурсы из проекта .Net 2.0 одновременно.
Ответ 5
У меня была такая же проблема.
Я отремонтировал .net 4.5.1 и исправил его.
Ответ 6
Недавно у меня было такое же сообщение об ошибке, когда клиент попросил меня понизить приложение.
Использование Visual Studio 2010 Professional Я изменил целевую структуру с .NET Framework 4 на .NET Framework 3.5. Построение с ошибкой завершилось с указанным сообщением об ошибке. Решение заключалось в том, чтобы удалить файл образа, вызывающий проблему из ресурсов приложения. Добавив его снова, версия System.Drawing была указана как 2.0.0.0, а создание выполнено успешно.
Ответ 7
Я столкнулся с той же проблемой, и ни одно из вышеперечисленных предложений не работало для меня, поэтому я сделал следующее:
Откройте проект
Перейти к Обозреватель решений
Развернуть справочную группу
Удалить ссылку System.Drawing
Щелкните правой кнопкой мыши на справочной группе
Добавить ссылку
На вкладке ".NET" найдите System.Drawing, чтобы добавить правильную ссылку
Ответ 8
У меня была такая же проблема.. с моей инфраструктурой 2.0 Project продолжал ссылаться на 4.0 dll. То, как я смог это исправить... просто перейдите к ссылке на проект → выберите "Syste.Drawing" → Свойства и там выберите точную версию = true
Это заставит использовать dll 2.0 framework.
Надеюсь, что это поможет.
Ура!!!
Ответ 9
Я также столкнулся с этой проблемой, и в моем случае причиной было создание двух по существу дублирующих проектов параллельно, один из которых нацеливался на .NET 2.0, а другой - на .NET 4.0, оба из которых содержат в основном один и тот же код и ресурсы. Если бы время было правильным, проект 2.0 собирал выходной файл из проекта 4.0 и в итоге ссылался на библиотеки 4.0.
Я исправил это, построив проекты последовательно, заставив их зависеть от другого.
(Я понимаю, что это, вероятно, не было причиной исходной проблемы, опубликованной @Leonardo, но это может быть полезно для будущих посетителей, которые сталкиваются с этой ошибкой с аналогичной настройкой с двумя проектами.)
Ответ 10
Я встретил ту же проблему в проекте Xamarin
Действительно, это не будет работать в Xamarin, так как это windows dll.
Взгляните на обсуждение,
https://forums.xamarin.com/discussion/14340/adding-a-reference-to-net-assembly
Ответ 11
Это не относится к ситуации OP, но если вы получаете эту ошибку в связи с использованием класса ResourceWriter
для преобразования файла .resx
файл .resources
, тогда читайте дальше. Я столкнулся с этой ошибкой, и единственный способ, которым я "System.Drawing, Version=4.0.0.0"
исправить это, - это сканировать данные для "System.Drawing, Version=4.0.0.0"
и заменить его "System.Drawing, Version=2.0.0.0"
. Здесь мой код (это часть модификации Roslyn):
/// <summary>
/// Method that gets called by ManagedResource.WriteData() in project CodeAnalysis during code
/// emitting to get the data for an embedded .resx file. Caller guarantees that the returned
/// MemoryStream object gets disposed.
/// </summary>
/// <param name="resourceFullFilename">full path and filename for .resx file to embed</param>
/// <param name="targetLessThan4">true if necessary to change System.Drawing from 4.0.0.0 to 2.0.0.0</param>
/// <returns>MemoryStream containing .resources file data for the .resx file</returns>
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
private static MemoryStream ProvideResourceDataForResx(string resourceFullFilename,
bool targetLessThan4)
{
MemoryStream shortLivedBackingStream = new MemoryStream();
using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream))
{
using (ResXResourceReader resourceReader = new ResXResourceReader(resourceFullFilename))
{
IDictionaryEnumerator dictionaryEnumerator = resourceReader.GetEnumerator();
while (dictionaryEnumerator.MoveNext())
{
string resourceKey = dictionaryEnumerator.Key as string;
if (resourceKey != null) // Should not be possible
resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value);
}
}
}
// Get reference to the buffer used by shortLivedBackingStream, which is now closed because
// resourceWriter was disposed. If relevant, fix version number for System.Drawing.
byte[] backingStreamBuffer = shortLivedBackingStream.GetBuffer();
if (targetLessThan4)
ChangeSystemDrawingVersionNumber(backingStreamBuffer);
// Create new MemoryStream because shortLivedBackingStream is closed
return new MemoryStream(backingStreamBuffer);
}
/// <summary>
/// Method to change the System.Drawing version number from "4.0.0.0" to "2.0.0.0" in the
/// binary data that represents a .resources file. This implementation is based on the
/// assumption that character data in the .resources file is in UTF-8 encoding.
/// </summary>
private static void ChangeSystemDrawingVersionNumber(byte[] dataBuffer)
{
byte[] byteArray1 = Encoding.UTF8.GetBytes("System.Drawing, Version=4.0.0.0");
byte[] byteArray2 = Encoding.UTF8.GetBytes("System.Drawing, Version=2.0.0.0");
for (int i = 0; i < dataBuffer.Length - byteArray1.Length; i++)
if (ArrayEquals(byteArray1, dataBuffer, i))
Array.Copy(byteArray2, 0, dataBuffer, i, byteArray2.Length);
}
/// <summary>
/// Method to test for a byte array in a larger byte array that is being searched. No error
/// checking is done - it assumed an indexing error is not possible.
/// </summary>
private static bool ArrayEquals(byte[] searchArray, byte[] searchedArray,
int searchedArrayIndex)
{
for (int i = 0; i < searchArray.Length; i++)
if (searchArray[i] != searchedArray[searchedArrayIndex + i])
return false;
return true;
}
Изменение: в предыдущей версии этого ответа я использовал метод ResourceWriter.TypeNameConverter
. Это работало в некоторых ситуациях, но не в других, и там есть отчет об ошибке, который указывает, что могут быть проблемы с этим кодом, по крайней мере для соответствующего кода в.Net Core: https://github.com/dotnet/corefx/issues/11083.
Ответ 12
Вот простое решение, которое сработало для меня:
У меня была такая же ошибка. Мой код является примером в пакете EMGU FeatureMatching с использованием VS2017.
Кажется, что ошибка возникает из-за несоответствия между версией System.Drawing.dll и Target Framework.
Чтобы исправить это, я удалил System.Drawing (щелкните правой кнопкой мыши в обозревателе решений в разделе "Ссылки"). Затем я щелкнул "Добавить ссылку" (щелкните правой кнопкой мыши "Ссылки" в обозревателе решений) и перешел к следующей папке: C:\Windows\Microsoft.NET\Framework\
В нем находятся папки с метками v1.xxxx, v2.xxxx, v3.xxxx и т.д. Я открыл папку v4.0.30319 и выбрал в ней файл System.Drawing.dll. Нажмите Ok.
Затем я перешел к установке Target Framework. Перейдите в меню Project> YourApp Properties (внизу меню). Выберите приложение слева. Есть раскрывающийся список для "Целевой рамки". Я выбрал .NET Framework 4 ". Я получаю сообщение о страшной потере чего-либо и о том, что проект будет закрыт и вновь открыт. Я нажал кнопку" ОК ", проект закрылся и сразу же открылся.
Я запустил свой проект, и теперь он в порядке.