views:

820

answers:

3

Is there any way to set a custom path to Program Database files (*.pdb) in C# under Visual Studio 2008? With C++ this was quite simple (Project settings -> Linker -> Debugging -> Generate Program Database File), but for some reason Microsoft seems to have removed (or hidden) it for C#.

I'm aware that the "standard" usage is to have pdb's located in the bin dir alongside the executable, but that directory is becoming quite a mess so I'd really prefer for them to be located in /obj, which is what I always used to do in C++.

Thanks!

A: 

add postbuild event and copy a pdb to desired location)

alexm
Then VS will just rebuild them everytime I try to run the app from within VS (even if nothing changed). Also, wouldn't that prevent VS from knowing where they are for the sake of debugging? I'm pretty sure VS needs to be told where they are.
Metal450
i just realized that he just needs them to be copied for no concrete action, i mean sometimes u provide a debug version build for testers etc. and u need to put pdb into some concrete folder.U're right with your comment.
alexm
A: 

The .pdb files has to reside in the same folder as your .exe and .dll's in order to load.

Pdb files are loaded upon exception handling, and needed for tracing back to the exact line in the code where your exceptions happens.

What you can do is move the pdb's to a symbol server during build instead of publishing them with the application. Then pull them in when analyzing an exception trace.

Check out this post for information about pdb files, symbol servers and more.

Mikael Svenson
*The .pdb files has to reside in the same folder as your .exe and .dll's in order to load.*>>That's not really true, as mentioned above: with C++ projects you can specify pdb's to be wherever you want and VS will load them just fine. Also, in C# projects you can put DLLs in another dir by adding to app.config: `probing privatePath="DLLs"`*What you can do is move the pdb's to a symbol server during build instead of publishing them with the application*>>True, but somehow that seems overcomplicated when all I want is have them reside in another dir. Did M$ really make this impossible?
Metal450
Reside in the same folder as the dll "for .Net" would be better worded.Probingpath does not seem to work./pdb switch on csc.exe with a path did not work. Different filename was no problem, but the pdb still had to be in the same folder as the .dll/.exe it was created for.I agree a symbol server is complicated, but seems to be the only alternative if you can't live with the .pdb's together with .dll's (in .Net apps) :) I hope someone can find a better solution.
Mikael Svenson
+2  A: 

The C# compiler supports this with the /pdb command line option. That option is however not exposed in the IDE's Build tab.

The IDE build process already asks the C# compiler to put the .pdb file in the obj\Debug directory. A copy of it ends up in the bin\Debug by a MSBuild task named CopyFilesToOutputDirectory. This task is configured in Microsoft.Common.targets, a file located in the c:\windows\microsoft.net\framework\v3.5 directory for VS2008. You could technically edit this file and remove the <Copy> element that copies the .pdb. Heed the warning at the top of file, be sure to make a backup copy before you modify it.

I think the basic problem you'll encounter doing this is that this affects all builds of all projects. And that the debugger now no longer can find the .pdb file. That would be the ultimate show-stopper.

Hans Passant
Good information - but yeah, it's still not ideal because as you mention, the debugger won't be able to find the .pdb files. Compare with the C++ example, in which the debugger finds the .pdb's just fine from whatever path you specify (not *only* the bin directory). It's still difficult for me to believe that MS would've made this impossible to accomplish for C#, that there's no "hidden way" to tell the development environment to place *and utilize* pdb's from some alternate path...
Metal450
@Metal: I feel a little weird having to say this, but C# isn't C++. (Thanks for not referring to MS with a $ in this comment.)
Greg D
Obviously I know that, I'm merely using it as an example - to show that the IDE/debugger is without a doubt capable of reading pdb's from wherever it wants (i.e. there's not some limitation that says they "have" to be in the same dir as the .exe). Thus, since the IDE knows how to load pdb's from elsewhere, there's no reason it shouldn't be able to do so for any language it supports. It's simply a path-setting issue. So for whatever reason Microsoft decided to dissalow this option, I can't help believe that there must still be some way to tell it to use a different path.
Metal450
The compiler embeds the path to the .pdb in the .exe. That path is obj\Debug. Not copying the .pdb should work. Have you actually tried my approach?
Hans Passant
I tried compiling a program with /pdb:path/test.pdb. The file generated nicely, but was not loaded. If I moved it to the location of the .exe, it was loaded fine with the different name.
Mikael Svenson
Hmm...I assume that if I see __'proj.exe' (Managed): Loaded 'C:\proj\bin\Debug\proj.exe', *Symbols loaded*."__ it means that the PDB was found and loaded? Then yes, it seems like removing PDB section from CopyFilesToOutputDirectory in Microsoft.Common.targets doesn't actually prevent the debugger from finding the .pdb file (in the obj dir)! I wonder what in the world is the point of having them copied to the bin directory at all, then? Unless I'm misunderstanding something?
Metal450
It's a bit of an accident. A happy one in your case. Not sure if this will work in all possible cases, you might have some trouble with copied reference assemblies.
Hans Passant
Seems to work alright for copied reference assemblies too - awesome! :) Just one problem though: since the pdb's are no longer being duplicated in the /bin directory, every time I start a debug session it detects that they're missing and rebuilds them (even though they're in actuality being loaded from the obj folder, as discussed above, which *does* still contain them). I had a look through Microsoft.Common.targets, but it wasn't obvious to me what needed to be changed to remove this dependency check...?
Metal450