4

I am able to place breakpoints and examine variables for a .NET dll loaded with 'Assembly.LoadFile', however, for some reason the visualizer for the Generic List doesn't show any of the elements (as seen below). The same thing shows in the watch window as when I hover over the variable.

I have examined these different solutions, but none seem to work (it also seems they mostly deal with not even being able to debug the dll):

Debug dynamically loaded assembly

Debug dynamically loaded assembly in Visual Studio .NET

I put the pdb side by side with the dll (from the exact location it is loaded from). I also put that dll's pdb file right next to the executable that was doing the loading, and still no dice. I am compiling in Debug, and have set all configurations to x86. One thing to note, if I actually put add the dll as a Reference, the debug visualizer shows up perfectly (however, this is a plugin architecture, and the exe shouldn't have to have a dependence upon the dll).

Any ideas?

[Edit]

It turns out that I cannot just add the plugin as a Reference, I have to actually instantiate a List of that type in my exe before it can be displayed properly, not sure what's going on...

[Edit]

I made this sample project which exhibits the behavior. I used similar code to how I was loading plugins (though interestingly enough, just calling Assembly.LoadFile directly and invoking a method via reflection doesn't seem to cause the behavior. I zipped up the sample project here: (does anyone else get the same results?)

http://dl.dropbox.com/u/64502227/PluginLoader.zip

[Edit]

Another interesting development! I have a Plugins folder next to the exe, where all the dlls go. Currently, I am copying the plugin dll/pdb into both the exe directory, and the Plugins sub directory. If I use Assembly.LoadFile and use the dll in the Plugins directory, I lose the List visualizer for my own types. If I load the dll right next to the exe, it works, but why?

What I see:

enter image description here

Community
  • 1
  • 1
Trevor Sundberg
  • 1,584
  • 1
  • 14
  • 25
  • 1
    Can you show us the code in which you load your DLL and PDB? – Polity Apr 28 '12 at 05:35
  • 1
    @Polity I added a link to an example project that exhibits the same behavior: http://dl.dropbox.com/u/64502227/PluginLoader.zip – Trevor Sundberg Apr 28 '12 at 20:56
  • Yet another breakthrough, if I load through the Plugins directory, AND use Activator.CreateInstance and pass in the Type, it fails. However, if I instead use the line: Activator.CreateInstance(assembly.FullName, "SamplePlugin.MyPlugin").Unwrap(), it works. I think the key is the 'Unwrap', but I'm not sure what that's doing for the debugger. Also, I updated the sample PluginLoader (much more concise and clearly outlines the error). – Trevor Sundberg Apr 28 '12 at 21:34

3 Answers3

1

Solution A:

  • Load all dlls from the exe directory and not their own directory.

Solution B:

Use this to create the plugin:

Plugin plugin = (Plugin)Activator.CreateInstance(assembly.FullName, "SamplePlugin.MyPlugin").Unwrap();

Instead of this:

Plugin plugin = (Plugin)Activator.CreateInstance(assembly.GetType("SamplePlugin.MyPlugin"));

I would figure that the second line of code would actually just internally be called by the first line of code (eg the first line would have to look up the assembly by name, then find the type "SamplePlugin.MyPlugin" out of it, then Unwrap() it to return it), but apparently not.

Unfortunately, this is a solution to the problem, but it doesn't answer WHY it happens. If anyone knows, I would still greatly appreciate the information.

Trevor Sundberg
  • 1,584
  • 1
  • 14
  • 25
0

You can always use the immediate window and do:

string.Join("\r\n", roots);

Or the long version, to include indices:

string.Join("\r\n", items.Select((index, item) =>
                string.Format("{0}: {1}", index, item)));

Or have a global function that does exactly that, so the use of it will be prettier, like:

Print(roots);

And:

public static void Print<T>(IEnumerable<T> items)
{
    Debug.WriteLine(string.Join("\r\n", items.Select((index, item) =>
                        string.Format("{0}: {1}", index, item))));
}
SimpleVar
  • 14,044
  • 4
  • 38
  • 60
  • This would work, but it gets pretty tedious to examine an entire tree this way(every node has a List of children). I'm looking more for an answer than a work around, but thank you. – Trevor Sundberg Apr 28 '12 at 04:03
  • You can wrap it with your own class, just for debugging purposes, and watch `new TreeWrapper(items);` – SimpleVar Apr 28 '12 at 04:04
  • 1
    Since when is it possible to use lambda's in the immediate window? apart from that, the debug visualizer should 'just' work, this doesn't really answer the question – Polity Apr 28 '12 at 05:35
0

Verify one of the VS options: Tools --> Options --> Debugging --> General, scroll down and ensure that "Show raw structure of objects in variables window" in unchecked.

Chris O
  • 5,017
  • 3
  • 35
  • 42