Au fil des flows

4jan/126

Voir une image sur le debugger de Visual Studio

Posted by Fabien Arcellier

L'absence dans visual studio d'une fonction pour visualiser une image au debug peut paraitre étonnanet. J'avais à mettre en forme une image. Même si je ne suis pas adepte du debugger, cette fonctionnalité me manquait. Ca m'ennuyait de devoir enregistrer un fichier ou de créer un formulaire dans le code pour voir le résultat en cours de route.

Depuis Visual studio 2005, l'IDE offre une possibilité très intéressante. Celle de pouvoir rajouter une vue rapide entièrement personnalisée sur n'importe quel type d'objet. Voila comment Tomer Noy a comblé cette absence. Il a ecrit un article sur codeproject qui explique comment le faire en 10 lignes de code.

A voir la simplicité de mise en oeuvre, on dirait que c'est presque volontairement que Microsoft n'offre pas cette possibilité en natif. Ainsi le developpeur peut découvrir par lui même les capacités de visual studio.

Voici le code source qu'il propose :

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Microsoft.VisualStudio.DebuggerVisualizers;
  5. using System.Windows.Forms;
  6. using System.Drawing;
  7.  
  8. [assembly: System.Diagnostics.DebuggerVisualizer(
  9. typeof(ImageVisualizer.DebuggerSide),
  10. typeof(VisualizerObjectSource),
  11. Target = typeof(System.Drawing.Image),
  12. Description = "Image Visualizer")]
  13. namespace ImageVisualizer
  14. {
  15.     public class DebuggerSide : DialogDebuggerVisualizer
  16.     {
  17.         override protected void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
  18.         {
  19.             Image image = (Image)objectProvider.GetObject();
  20.            
  21.             Form form = new Form();
  22.             form.Text = string.Format("Width: {0}, Height: {1}", image.Width, image.Height);
  23.             form.ClientSize = new Size(image.Width, image.Height);
  24.             form.FormBorderStyle = FormBorderStyle.FixedToolWindow;
  25.            
  26.             PictureBox pictureBox = new PictureBox();
  27.             pictureBox.Image = image;
  28.             pictureBox.Parent = form;
  29.             pictureBox.Dock = DockStyle.Fill;
  30.  
  31.             windowService.ShowDialog(form);
  32.         }
  33.     }
  34. }
  35.  

Pour que ça fonctionne, vous devez compiler le projet. Pour le déploiement, il suffit de placer l'assembly obtenu (ImageVizualizer.dll) dans le dossier suivant <Visual Studio Install Dir>\Common7\Packages\Debugger\Visualizers.

Pour les utilisateurs de Visual studio 2010, vous ne pourrez pas directement compiler son projet. Il vous faut redéfinir la référence vers l'assembly Microsoft.VisualStudio.DebuggerVisualizers. Vous devrez aller le chercher dans le dossier C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0.

Pour les utilisateurs de Visual studio 2008, l'assembly se trouve dans la liste des références dotNet.

Comment ca fonctionne ?

Vous héritez de la classe DialogDebuggerVisualizer. L'attribut en entête du namespace va permettre à Visual studio d'enregistrer votre plug in.

Ensuite, vous surchargez la méthode protege Show de DialogDebuggerVisualizer. Lors de l'invocation de cette methode, une Form est crée dynamiquement. Elle contient PictureBox dans laquelle le debugger va charger l'image. Ensuite, l'IDE invoque la form au travers de la ligne windowService.ShowDialog(form).

Telechargement

J'ai repris le code proposé par Tony pour ajouter un menu contextuel avec la fonction copie.

Code source du projet :  ImageVisualizer (Code source)

Assembly : ImageVisualizer (assembly)

Remplis sous: Non classé 6 Commentaires
3jan/125

System.IO.FileNotFoundException: Could not load file or assembly ‘System.Data.SQLite.dll’

Posted by Fabien Arcellier

Aujourd'hui, j'ai rencontré ce message d'erreur sur une application que je développe. Plaçons rapidement le contexte, il s'agit d'un outil développé avec .NET4 qui permet de gérer le contenu d'une base de donnée sqlite.

Ma machine de développement est sous Windows 7 64bits. Ce problème est apparu lors du test de l'application sur une machine équipée d'un Windows Vista 32bits.

Voici l'exception complète que j'ai relevé dans le trace.log :

02/01/2012 18:31:10
Exception Not handled
System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.SQLite.dll' or one of its dependencies. Le module spécifié est introuvable.
File name: 'System.Data.SQLite.dll'
 ... [Suivi de son stacktrace]

La première piste que j'ai suivi, vu que je venai de la machine de développement, c'est l'absence du fichier System.Data.SQlite.dll dans le GAC. Cette piste m'a mené nulle part. L'erreur c'etait de se focaliser sur le type de l'exception FileNotFoundException.

Par hasard, en venant remplacer le fichier System.Data.SQLite.dll qui se trouvait à coté de l'application, j'ai obtenu un message d'erreur différent. Celui ci m'indiquait que la signature de l'assembly ne correspondait plus. Ca signifiait qu'il trouvait bien l'assembly System.Data.SQlite.dll mais qu'il n'arrivait pas à le charger

Au final, j'ai pu résoudre ce problème en utilisant une Dll différente. Sur la page de ce provider de données, plusieurs distributions sont proposées.

Sur la version qui me donnait une erreur, j'utilisai la version sqlite-netFx40-binary-bundle-Win32-2010-1.0.77.0.zip. En utilisant sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0.zip, le problème n'apparaissait plus.

Quel est le souci  ?

A dire la vérité je n'en suis pas certain. Ayant parcouru la toile, certaines personnes semblent avoir  rencontré un problème très similaire.

Le fournisseur de donnée System.Data.SQLite.dll encapsule la librairie en code natif sqlite3.dll. Contrairement au code managé de System.Data.SQLite.dll, ce code ne peut s'exécuter que sur la plate forme à  laquelle il est destinée. La où je ne comprends pas c'est que ma plateforme cible à la compilation et de la dll ont été choisi pour avoir comme cible des processeurs x86, c'est à dire 32bits.

Le lien statique évite que le code soit chargé par l'OS pour pouvoir l'utiliser. Le programme vient attaquer directement les fonctions de la Dll. Je pense que c'est là où se trouve un morceau de l'explication. C'est le chargement qui est bloquant. Peut etre que le souci vient du wrapper autour de sqlite3.dll mais difficile de conclure...

Voici un shéma la différence entre un lien statique et un lien dynamique (tiré d'un sujet sur stackoverflow)

Comparaison Lien Statique Dynamique

Comparaison Lien Statique Dynamique

Avez vous déjà rencontré un problème similaire ? Avez vous une explication plus convaincante ?

 

 

Remplis sous: Non classé 5 Commentaires