web-dev-qa-db-fra.com

Erreur "Impossible de charger le fichier ou l'Assembly System.Drawing ou l'une de ses dépendances" sur .Net 2.0, VS2010 et Windows 8

Je reçois une exception FileNotFoundException sur un projet d'application Windows Forms, avec le message suivant: 

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.

Pour reproduire le problème: 

  • Sélectionnez Nouveau, Projet, choisissez .Net Framework 2.0 comme cible et choisissez Application Windows Forms comme type de projet.
  • Dans les propriétés du formulaire créé par défaut, sélectionnez une valeur pour la propriété Icon. Tout fichier .ico fera l'affaire. Cela incorporera le fichier sur le fichier resx.
  • Compiler et exécuter l'application.

Lorsque je fais cela, le programme s’arrête sur la ligne this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); avec l’exception suivante:

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

Je reçois ce message sur Visual Studio 2010 SP1, récemment installé sur Windows 8 Developer Preview. Si je modifie les propriétés du projet pour cibler .Net Framework 4, l'erreur disparaît.

Sur le fichier Form1.resx, je peux voir que la version de System.Drawing Assembly est explicitement définie en tant que 2.0:

<Assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

Des idées?

16
Leonardo

J'ai trouvé une solution possible, essayez ceci:

Ouvrez le fichier resx dans Designer et définissez le modificateur d’accès de public sur aucune génération de code.

Edit: il existe une solution de contournement, mais très ennuyeuse.

  1. Ouvrez un formulaire dans Designer et apportez les modifications nécessaires à l'interface graphique. Fermer le concepteur et sauvegarder
  2. Compiler le projet et recevoir une erreur de compilation RESX (seuls les formulaires avec Imagelist devraient avoir ce problème)
  3. Double-cliquez sur Erreur de compilation resx pour ouvrir le fichier resx. 
  4. Faites défiler vers le haut de imagestream.
  5. Vous avez le choix sur votre profil
  6. Fermez et enregistrez le fichier resx et recompilez. 

** REMARQUE: la seule différence concerne les caractères situés à la fin "j00LjAuMC4w" à "j0yLjAuMC4w" Cette opération doit être effectuée À CHAQUE FOIS que vous ouvrez le formulaire en mode Designer.

Microsoft dit qu'ils vont le réparer dans la prochaine version de VS ...

Source: http://connect.Microsoft.com/VisualStudio/feedback/details/532584/error-when-compiling-resx-file-seems-related-to-beta2-bug-5252020

4
vulkanino

C'est un bug. Je l'ai vu aussi. Cela se produit parce que votre fichier .resx pointe vers la version 4.0.0.0 de System.Drawing là où il n'en existe pas. Pour résoudre ce problème, je modifie généralement le fichier .resx dans le bloc-notes afin de passer de 4.0.0.0 à 2.0.0.0. Le bogue est introduit en suivant les étapes exactes que vous avez décrites.

9
Sudarshan chandan

Ce problème peut se produire si .net 4.5 preview resgen est utilisé pour créer les fichiers de ressources. 

J'ai le même problème sur mon ordinateur portable (Windows 7, VS2010 Premium, VS11 Developer Preview). J'ai ce problème avec un projet de formulaire simple lorsque je dis 'localisable = vrai' sur un formulaire. Dans mon cas, aucune image n'est impliquée. Le projet est défini sur .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, 

Si je copie ensuite ce projet sur une autre machine (Windows 7, VS2010 Premium) et essaie de le déboguer, l’erreur persiste. L'erreur disparaît si je nettoie la solution (pas le projet) (ou supprime bin/obj à la main) Si je copie ensuite cette solution sur mon ordinateur portable, l'erreur disparaît, mais je ne peux pas voir le formulaire à nouveau dans la vue de conception 'Error message: at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.EnsureDocument(IDesignerSerializationManager manager)'

La raison de tout cela semble être la version .net dans les fichiers * .Designer.cs. 

  1. Version d'exécution: 4.0.30319.239 sur l'ordinateur sur lequel cela fonctionne, 
  2. Version d'exécution: 4.0.30319.17020 sur l'ordinateur portable où j'obtiens l'exception.

Quelqu'un peut-il me dire où je peux configurer la version de resgen utilisée pour traiter des projets .net 3.5?

5
Manuel

J'ai eu ce problème et je l'ai trouvé bizarrement dû à .Net 4.5 beta. La désinstallation et la réinstallation de .Net 4.0 ont résolu le problème. Vous ne savez pas s'il existe un moyen d'installer .Net 4.5 beta et simultanément en utilisant les ressources d'un projet .Net 2.0.

1
Dax Fohl

J'ai eu le même problème. 

J'ai réparé .net 4.5.1 et il l'a corrigé.

1
Jon

J'ai rencontré le même problème et aucune des suggestions ci-dessus n'a fonctionné pour moi, alors j'ai fait ce qui suit: 

Ouvrez votre projet
Aller à l'explorateur de solutions
Développer le groupe de référence
Supprimez la référence System.Drawing
Cliquez avec le bouton droit sur Groupe de référence
Ajouter une référence
Sous l'onglet ".NET", recherchez System.Drawing pour ajouter la bonne référence.

0
NG.

J'ai également rencontré ce problème et la cause dans mon cas était la construction de deux projets essentiellement dupliqués en parallèle, l'un ciblant .NET 2.0 et l'autre ciblant .NET 4.0, tous deux contenant principalement le même code et les mêmes ressources. Si le moment était opportun, le projet 2.0 prendrait un fichier de sortie du projet 4.0 et finira par référencer des bibliothèques 4.0.

Je l'ai corrigé en construisant les projets en série, en faisant dépendre les uns des autres.

(J'apprécie le fait que ce ne soit probablement pas la cause du problème initial publié par @Leonardo, mais cela peut être utile pour les futurs visiteurs qui rencontrent cette erreur avec une configuration similaire à deux projets.)

0
RichieHindle

J'ai eu le même problème .. avec mon framework 2.0 Project continuer à référencer 4.0 dll. La façon dont j'ai pu résoudre le problème ... allez simplement dans la référence de votre projet -> sélectionnez "Syste.Drawing" -> Propriétés et sélectionnez ensuite utiliser version exacte = true

Cela obligera à utiliser 2.0 framework dll.

J'espère que cela t'aides.

À votre santé!!!

0
user4784388

J'ai récemment eu le même message d'erreur lorsqu'un client m'a demandé de rétrograder une application.

À l'aide de Visual Studio 2010 Professional, j'ai modifié le framework cible de .NET Framework 4 à .NET Framework 3.5. La construction a ensuite échoué avec le message d'erreur spécifié. La solution consistait à supprimer le fichier image à l'origine du problème des ressources de l'application. En l'ajoutant à nouveau, la version de System.Drawing était répertoriée en tant que 2.0.0.0 et la construction a réussi.

0
Journeyman

Cela ne concerne pas la situation du PO, mais si vous obtenez cette erreur liée à l'utilisation de la classe ResourceWriter pour convertir un fichier .resx en un fichier .resources, poursuivez votre lecture. J'ai rencontré cette erreur et la seule solution que j'ai trouvée pour résoudre ce problème consistait à analyser les données pour "System.Drawing, Version=4.0.0.0" et à les remplacer par "System.Drawing, Version=2.0.0.0". Voici mon code (cela fait partie d'une modification de 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's 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;
  }

Edit: Dans une version précédente de cette réponse, j'ai utilisé une méthode ResourceWriter.TypeNameConverter. Cela a fonctionné dans certaines situations, mais pas dans d'autres, et un rapport de bogue indique qu'il peut y avoir des problèmes avec ce code, du moins pour le code correspondant dans .Net Core: https://github.com/dotnet/corefx/issues/11083 .

0
RenniePet

J'ai rencontré le même problème dans Xamarin Project  

Vraiment cela ne fonctionnera pas dans Xamarin puisqu'il s'agit de windows dll. 

Regardez la discussion,

https://forums.xamarin.com/discussion/14340/adding-a-reference-to-net-Assembly

0
Gobi M