My ASP.NET webpage requires some data provided by a C++ .NET DLL. Everything seemed to work fine as far as loading this DLL and calling functions in it at first, but now my project seems to have gotten into a state where it does not actually debug if I reference the DLL in the .cs file.
I commented out all of the code that references the DLL and removed the reference from my project, and it worked fine. I added a reference to the DLL back in, and it worked fine. I uncommented only the using statement for the DLL’s namespace (using MDnlnkCmdReader; in this case), leaving no actual code referencing the DLL, and now, when I hit debug, none of my breakpoints hit. Comment out that line again, and the breakpoint hits again.
When it gets into this state where the webpage appears to load correctly but none of the breakpoints hit, if I switch back to the source code and view the breakpoints, they show up as an outline with a caution flag, and if I mouseover them, then it says “The breakpoint will not currently be hit. The source code is different from the original version”
I looked up that error message too and tried the usual solutions to it. If I nuke the entire /bin folder, then I start getting webserver error messages about global.asax. These persist until I build in Any CPU mode (normally building in x64), at which point I get “unable to load” messages about the DLL (built in x64). When I delete the reference to it, then the page works again. Switch back to x64 mode and add the reference back in, and I’m right back where I started. Rebooting doesn’t seem to help either.
Any ideas what’s going on here, and how to get out of it?
Okay, I think I have this figured out now. What I have been dealing with is actually two different issues.
The first issue is that the ASP.NET development server seems to only be willing to grab its DLLs from the projects’s
/binfolder. Your project will build there if it is set to Any CPU, but if it is set tox86orx64, then the default is to build inbin/x86/Debugorbin/x64/Debug. If you are set tox86orx64with the default build locations, then the development server will still try to grab DLLs from the root of the/binfolder.If you have never built your project as
Any CPU, or have cleaned out the/binfolder since the last time you have, then it will not find your DLLs at all, and the development server will display an error message like “Could not load type ‘WebDownlink.Global’.” about yourGlobal.asaxfile (whereWebDownlinkis the namespace of your project). This means that it cannot load your namespace, which is because it cannot find your DLLs because it is only looking in the root of the/binfolder.If you have built your project as
Any CPUand then switched to building it inx86orx64, then your new build will be in the appropriate subdirectory, but the development server will still grab the files from your lastAny CPUbuild. The Visual Studio debugger will be using the files you just built, though, so if you have changed anything since your lastAny CPUbuild, you will get the different source code error and debugging won’t work right. If you haven’t changed anything, then debugging will work, but the development server will still be running theAny CPUversion, which may confuse the heck out of you if you are trying to do anything where bittedness matters.The correct solution to this seems to be to configure your
x86mode to build in the root of the/binfolder rather than the/bin/x86/Debugfolder. Or maybe don’t reference any unmanaged DLLs in the first place.This dovetails into the second issue, which is that the ASP.NET development server runs in 32-bit mode only, while the IIS application pool on a 64-bit system runs in 64-bit mode only (if you know of a way to change either of these, please let me know). If you need to link your code to an unmanaged DLL that can’t be built as
Any CPU, you will have to account for this. That’s why I only referencex86above – there’s no point in changing where yourx64builds because the development server won’t run it anyway.Luckily, I have the source for the DLL that my code references, and it doesn’t reference anything else, so I can easily built it in both 32- and 64-bit mode to run it on both the development server and the full IIS. If you are referencing a 32-bit DLL that you can’t rebuild, then you will either have to deploy on a 32-bit machine or figure out some way to get the IIS application pool to run in 32 bit, which I couldn’t. If your DLL is 64-bit and can’t be rebuilt, then you’ll just have to do all of your debugging of code related to it on the full IIS.
So my solution is to build my DLL in 32 bit, reset the reference, and then build in 32 bit mode, with the output path set to
/bin. When I want to deploy, I rebuild the DLL in 64 bit, reset the reference, build the project in 64 bit, and then deploy to IIS.