0) How to debug unityContainer?
Im working on a legacy project on the firm, and all projects are loaded using dependency injection using unityContainer. I need to make improvements on the presentation layer, but I cannot debug the code, only the main project, witch loaded all modules.
The code used for loading modules(projects):
unityContainer.RegisterType("FrontEndModule", new InjectionMember[0]);
On the module, i register all project types like this:
unityContainer.RegisterType< IAboutPage, AboutPage>();
And then I run the main form:
Application.Run((Form) unityContainer.Resolve< IMainPage >() );
1) So there is any way to debug the code of the loaded projects?
2) Do I need to make any change to be able to debug?
I've tried to run the form directly, but then there is a lot of injections needed to run. Maybe I would be able to use another IoC framework that permit me to debug the code of loaded projects.
Thanks.
There is nothing special about Unity when you debug code.
To be able to steps through the code you need
PDB files matching to DLLs that you are using (often it means "rebuild locally" unless PDB published along with DLLs)
source code, preferably matching the version of the source used to build DLLs (VS will allow to use mismatched sources, but you'll likely get very poor experience when stepping through does not match what actually happening since line numbers in PDB no longer align with actual text source)
you may need to disable "Tools->Options->Debug->My code only" setting to allow stepping through/breakpoints in code outside of solution (that's depending on VS mood :) )
If you can't get PDBs you still can see exceptions and call-stacks (as this information is part of DLL metainfo).
Switching to another DI framework will not have any impact on that.
Related
I'm about to start developing a desktop application (WPF) based on a "plugin" architecture, and was going to use MEF (and its DirectoryCatalog) to discover and load plugin assemblies. We're going to be developing many plugins, so it seems sensible to keep them in separate VS solutions rather than bloat the "core" application solution, but having only ever worked on single, standalone solutions, I suspect this is going to make debugging a bit tricky. I'm using VS2013 if that makes a difference.
I'm assuming that I'll still be able to step into a plugin in scenarios where the "core" application calls a method in that plugin? And I'm guessing that once in there, I'll be able to set breakpoints in those source code files that have been "visited"? But what if I want to add a breakpoint to a different source code file - one that hasn't been visited while stepping-through? How can I open that file? In a single solution I could just open it via Solution Explorer, but not (I'm guessing) when it's in a separate assembly.
I'm trying to pre-empt any problems I might have with this multi-solution approach, and wondered if VS had any clever features to simplify some of this stuff. Having separate solutions also means first compiling the plugin solution(s) that I want to test, then compiling and running the "core" application solution. While it's only a couple of extra mouse clicks, are there (again) any VS features that could help here?
This is a common scenario and not tricky at all.
In the project properties of your plug-ins, go to Debug -> Start Action and set Start external program to the executable of your core application.
This way, you only have to compile your core application once (probably using a build script that just builds everything), and debugging a plug-in will start the core application with the debugger attached and you can debug the plug-in (as soon as your core apllication loads the plug-in assembly).
Also keep in mind that you can dettach the debugger from the running application, switch to another instance of Visual Studio with another solution opened, and again attach to your running application. This comes in handy if you e.g. debug your plug-in and want to set or use existing break points in your core application.
As long as Visual Studio is able to find the debugging symbols (the *.pdb files), stepping through the code of e.g. your core application while debugging your plug-in is also no problem.
I see two ways to do this.
The more comfortable option:
1. You can add the external solution to the core solution.
Walkthrough: Adding an existing Visual Studio solution to another solution
By doing this you can organize your solution to reference the code and still keep each plugin solution separate at the same time.
You just reference those plugin solutions from your core solution that you currently want to work on. Also, using this approach you can organize the other solutions just like you would with normal projects and move thembetween virtual solutios folders to your liking until you have the most adequate folder structure.
Quote from the article:
The nice thing about this approach is that not only are all the
projects now in one solution but at any time, you can open the
separate solutions without impacting the "master" solution and vice
versa.
The files in the references solution can be opened and edited just like any other file from your "normal" projects, and of course, you can set breakpoint like in any other code file, too.
This way you can both edityour code and step through it, which I personally find much more convenient than switching and attaching to multiple processes.
2. Add the PDB files.
Put the DLLs with their corresponding PDBs of those plugins you want to debug into a folder and configure your core application to use that folder for the DirectoryCatalog. This enables you to step into the plugin code, but you will not be able to edit them.
#Andrew
Regarding debugging, it shouldn't be an issue as long as you drop the .pdb files with assembly in directory which you are using as DirectoryCatalog.
Regarding building plugin solution before Core- as you have 1 build file for each solution, you should check if you can write msbuild commands in a .bat file to get it executed one after other.
Besides all the above suggestions, another way to debug is to attach your addin solution to the running core process. Attach to Running Processes with the Visual Studio Debugger
I have two projects in my solution Bridge and BridgeInterface being used by my applications update process and it's throwing a FileLoadException when I try to run use the Initialize() method from the Bridge class.
The problem is I can't step into this method, and I have run out of ideas, I need to see where the fault lies in the code!
The Bridge projects where not originally originally part of the solution, so I added both the projects and have pointed to their PDB symbol files. (The .DLL's are showing as symbols loaded in the modules window.)
I also have "Just My Code" unchecked and all projects in the solution are targetting the .NET 4 Full Profile.
Checked to see if the implementer was using DebuggerStepperBoundary or DebuggerStepThroughAttribute no such luck.
Any ideas?
Change the assembly references in your main project to use project references.
This way VS can compile the debug versions of the bridge projects and properly keep track of what's going on so you can step into it.
I'm trying to re-jig the layout of a very large solution which has become impossibly hard (and s l o w) to work with. My plan is to create a number of solutions containing related projects, and then use binary references where necessary to link to libraries produced by the other solutions.
The thing we rely on to make this usable is Resharper's Navigate to External Sources functionality, so we can easily browse the source of the projects we are referencing from other solutions. Quite why VS can't do this out of the box is beyond me.
This is all working very nicely for classes with implementation. However, for C# interfaces and classes containing only auto-implemented properties, Resharper isn't able to browse to the sources, and falls back to cruddy metadata viewer.
I used srctool.exe, which comes with the Symbol Server tools in MS Debugging Tools For Windows, to browse the sources listed in the .pdb file, and it's clear that the sources for these interfaces and empty(ish) classes are not referenced in the pdb file. If I switch the auto-implemented properties to those with backing fields, then the source link appears in the pdb.
I'm guessing the sources are excluded because there are no places you could set breakpoints on interfaces and auto-implemented properties.
I'm wondering, though, if there is some exotic compiler option or workaround we can employ to force the PDB file to include references to the source of C# interfaces.
Thanks,
Mark
The question doesn't have enough detail. Shooting off the hip, I'd guess that you tackled the problems with the slow massive solution by converting project references to assembly references. And used the Release build of those projects as the reference.
And yes, that stumps any tool that tries to find source code files from the PDB. The release build of a .NET project uses a stripped version of the PDB, all the source code file and line number info has been removed from it. That's a pretty normal thing to do with real release builds. Release built code normally is optimized. That causes code to be re-ordered, no longer matching the logical position of the code in the source file. Any info you get from the source+line PDB info now tends to get between harmful and useless, you start looking in the wrong place for a problem.
That is however not a concern for IDE tooling or while debugging your app. The optimizer is automatically disabled in a case like this. Actually a configuration item in VS: Tools + Options, Debugging, General, "Suppress JIT optimization on module load" option. Turned on by default.
Clearly any tooling that uses the PDB is going to catatonic when they don't have a chance to find source files. The fix is to go back to the original project, select the Release configuration again and change a setting: Project + Properties, Build tab, scroll down, Advanced button. Change the "Debug info" combo from "pdb-only" to "full". Rebuild the project.
Should fix your problem. Also revives the debugger, you can step into the source code again.
Don't move files around too much btw, you might stump the chumps again. At least keep the PDB with the DLL in the same directory. If the source code is no longer present in the same directory but you checked it out again in another one then you have to tell the IDE about it. Right-click the solution, Properties, Debug Source Files setting.
We're going to be using Orchard as a base for a particular client. We're a C# shop running VS2K10. We'll throw it in our version control system as per the norm for our projects.
That said, we'll be creating custom modules based on the needs of our clients. What approach does everyone here recommend?
Get full source from CodePlex and check that in
Download just the Orchard web code (similar to Web Platform Installer)
Problem with #1 is that the code base is rather large, but it will allow us to debug the site locally when developing.
What are the caveats with #2? Lack of debugging?
I'm curious what everyone's approach would be for this. I'm inclined to go with #1, get the full source, throw it in SVN, and build off of that.
Thoughts?
If you are going to develop modules using Visual Studio, just use the full source code. Disk space is cheap.
Caveats with #2 are that it's immensely less comfortable. Why bother?
I use the full source version, but I only check the modules and themes that I'm working on into source control.
I did originally use just the web code, but found myself running into lots of little problems that were much easier to track down when using the full source.
I found that only source controlling the stuff I was working on made updating to later versions of Orchard much easier.
I'm no software engineer, but here is what I would do :
Get the source code.
Add it in your VS solution and source control.
Do NOT reference the project(s).
Add a post-build event on that project to copy the dll and the symbols (for debug) in the folders of the project that would otherwise refer this one.
If it crashed in a class from that project's assembly, you'll be able to specify the source code files since you got the symbols, and since you won't be modifying that project on a regular basis, your VS won't rebuild it every time. You could even unload the project if you want to save some memory, however trivial it might be.
I'm getting System.IO.FileNotFoundException: The specified module could not be found when running C# code that calls a C++/CLI assembly which in turn calls a pure C DLL. It happens as soon as an object is instantiated that calls the pure C DLL functions.
BackingStore is pure C.
CPPDemoViewModel is C++/CLI calling BackingStore it has a reference to BackingStore.
I tried the simplest possible case - add a new C# unit test project that just tries to create an object defined in CPPDemoViewModel . I added a reference from the C# project to CPPDemoViewModel .
A C++/CLI test project works fine with just the added ref to CPPDemoViewModel so it's something about going between the languages.
I'm using Visual Studio 2008 SP1 with .Net 3.5 SP1. I'm building on Vista x64 but have been careful to make sure my Platform target is set to x86.
This feels like something stupid and obvious I'm missing but it would be even more stupid of me to waste time trying to solve it in private so I'm out here embarrassing myself!
This is a test for a project porting a huge amount of legacy C code which I'm keeping in a DLL with a ViewModel implemented in C++/CLI.
edit
After checking directories, I can confirm that the BackingStore.dll has not been copied.
I have the standard unique project folders created with a typical multi-project solution.
WPFViewModelInCPP
BackingStore
CPPViewModel
CPPViewModelTestInCS
bin
Debug
Debug
The higher-level Debug appears to be a common folder used by the C and C++/CLI projects, to my surprise.
WPFViewModelInCPP\Debug contains BackingStore.dll, CPPDemoViewModel.dll, CPPViewModelTest.dll and their associated .ilk and .pdb files
WPFViewModelInCPP\CPPViewModelTestInCS\bin\Debug contains CPPDemoViewModel and CPPViewModelTestInCS .dll and .pdb files but not BackingStore. However, manually copying BackingStore into that directory did not fix the error.
CPPDemoViewModel has the property Copy Local set which I assume is responsible for copying its DLL when if is referenced. I can't add a reference from a C# project to a pure C DLL - it just says A Reference to Backing Store could not be added.
I'm not sure if I have just one problem or two.
I can use an old-fashioned copying build step to copy the BackingStore.dll into any given C# project's directories, although I'd hoped the new .net model didn't require that.
DependencyWalker is telling me that the missing file is GPSVC.dll which has been suggested indicates security setting issues. I suspect this is a red herring.
edit2
With a manual copy of BackingStore.dll to be adjacent to the executable, the GUI now works fine. The C# Test Project still has problems which I suspect is due to the runtime environment of a test project but I can live without that for now.
Are the C and C++ DLLs in the same directory as the C# assembly that's executing?
You may have to change your project output settings so that the C# assembly and the other DLLs all end up in the same folder.
I've often used the Dependency Walker in cases like this; it's a sanity check that shows that all the dependencies can actually be found.
Once your app is running, you may also want to try out Process Monitor on the code you are running, to see which DLLs are being referenced, and where they are located.
The answer for the GUI, other than changing output settings, was the addition of a Pre-Build Step
copy $(ProjectDir)..\Debug\BackingStore.* $(TargetDir)
The answer for the Test projects was to add the missing DLL to the Deployment tab of the testrunconfig. You can either do so by directly editing the default LocalTestRun.testrunconfig (appears in Solution under Solution Items) or right-click the Solution and Add a new test run config, which will then appear under the main Test menu.
Thanks for the answers on this SO question on test configurations for leading me to the answer.
The reason why this happens is because you either are loading DLLMAIN from managed code, before the CRT has an opportunity to be initialized. You may not have any managed code, be executed DIRECTLY or INDERECTLY from an effect of DllMain notifications. (See: Expert C++/CLI: .Net for Visual C++ Programmers, chapter 11++).
Or you have no native entrypoint defined wahtsoever, yet you have linked to MSVCRT. The CLR is automatically initialized for you with /clr, this detail causes a lot of confusion and must be taken into account. A mixed mode DLL actually delay loads the CLR through the use of hot-patching all of the managed entry point vtables in your classes.
A number of class initialization issues surround this topic, loader lock and delay loading CLR are a bit trickey sometimes. Try to declare global's static and do not use #pragma managed/unmanaged, isolate your code with /clr per-file.
If you can not isolate your code from the managed code, and are having trouble, (after taking some of these steps), you can also look towards hosting the CLR yourself and perhaps going through the effort of creating a domain manager, that would ensure your fully "in-the-loop" of runtime events and bootstrapping.
This is exactally why, it has nothting todo with your search path, or initialization. Unfortunately the Fusion log viewer does not help that much (which is the usual place to look for .NET CLR assembly binding issues not dependency walker).
Linking statically has nothing todo with this either. You can NOT statically link a C++/CLI application which is mixed mode.
Place your DLLMAIN function into a file by itself.
Ensure that this file does NOT have /CLR set in the build options (file build options)
Make sure your linking with /MD or /MDd, and all your dependencies which you LINK use the exact same CRT.
Evaluate your linker's settings for /DEFAULTLIB and /INCLUDE to identify any possiable reference issues, you can declare a prototype in your code and use /INCLUDE to override default library link resolution.
Good luck, also check that book it's very good.
Make sure the target system has the correct MS Visual C runtime, and that you are not accidentally building the C dll with a debug runtime.
This is an interesting dilemma. I've never heard of a problem loading native .DLLs from C++/CLI after a call into it from C# before. I can only assume the problem is as #Daniel L suggested, and that your .DLL simply isn't in a path the assembly loader can find.
If Daniel's suggestion doesn't work out, I suggest you try statically linking the native C code to the C++/CLI program, if you can. That would certainly solve the problem, as the .DLL would then be entirely absorbed into the C++/CLI .DLL.
Had the same problem switching to 64-bit Vista. Our application was calling Win32 DLLs which was confusing the target build for the application. To resolve it we did the following:
Go to project properties;
Select Build tab;
Change 'Platform target:' option to x86;
Rebuild the application.
When I re-ran the application it worked.