'Symbols not loaded' when trying to debug dynamically loaded assemblies in VS.NET

Here is an interesting one for all those who are trying to debug DLL assemblies that you load dynamically in your application.

For example, you have a .Net DLL project in VS.Net 2003 that is set to launch a .Net EXE when you hit F5. In your EXE, using a File Open dialog, you select and then load your .Net DLL and run the code within it. So basically the DLL is not bound or declared to the EXE at compile time, but you still want to be able to set breakpoints in your DLL that get hit when required.

Assembly asm = Assembly.LoadFrom( “mydll.dll” );

This all works fine, you can use the classes in the assembly and debug from within VS.Net. However, the LoadFrom call does place a lock on the file that is only released when the main EXE unloads. Now this may not be an issue for you, but it was for us. You can get round this locking by creating your own Application Domain for loaded DLL assemblies but that is a bit complex. There is a simpler option; that is to load the DLL assembly via a FileStream

FileStream fs = new FileStream(“mydll.dll”,FileMode.Open);
new byte[fs.Length];
fs.Read(b,0,(int)fs.Length);
Assembly asm = Assembly.Load(b);

This places no lock on the file, so the underlying DLL file can be deleted/replaced/reloaded to your hearts content whist the EXE is running.

However there is a problem for debugging, in VS.Net you get the message that the breakpoint in your DLL can never be reached as the symbols are not loaded for the assembly. By the way the way to check what debug symbols (if any) are loaded is to use the Modules window in VS.Net Debug|Windows.

If you use LoadFrom the assembly is loaded and any associated debug symbols (.PDB files) if present, allowing VS.Net to debug into the assembly. This is not the case with the FileStream, you only load what you ask for, if you want a .PDB as well you have to load it manually. To do this you need to use FileStream twice, the first loads the DLL into one byte array, the second loads the .PDB into another byte array. Then use another form of the Load method using both arrays.

Hope this save someone the time it lost us !

Richard