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

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

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