Remco wrote:Hi, thanks for posting!
And thanks for responding.
Remco wrote:
In some application domains, the GetAssemblies().Select(x => x.Location) code will cause the exception you've described to be thrown. I've updated the documentation with an adjustment to this to avoid referencing System.Reflection.Emit assemblies which often are responsible for the exception. Try the following to see if it works any better:
var referencedAssemblyPathsInOuterAppDomain = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.ManifestModule.GetType().Namespace != "System.Reflection.Emit").Select(x => x.Location).ToArray();
Yes, this fixes the debugging problem and helped point me in the right direction.
Remco wrote:
If I correctly understand the relationship between these DLLs you've described, the Test project has an indirect dependency on Other.dll and you are working around this by introducing a relative cross-project dependency in the Test .csproj file. This sort of setup unfortunately can't work well with NCrunch's workspacing as the workspacing treats projects as being independent units that have been extracted from their parent solution (and thus they cannot indirectly rely on each other's build output outside of NCrunch's test environment wiring).
Not quite. Other.dll is 3rd party dll that I have placed in my solution's libs directory. I have made NC aware of that dependency by linking to the libs\other.dll file within MyProject.Interop.Test and setting it to copy when newer. When I check the NC output directory for the test project, other.dll is present.
Problem 1: CPU architecture autodetect failure.
With the code changes above, I was able to see all the assembly locations which made me wonder where the test runner was searching for other.dll. I pulled up ProcessMonitor and discovered that the dll was being found and read but not loaded, which made me realize that the platform/architecture must be wrong on the test project (as it's a 64-bit only dll). I had set the Interop project to a CPU architecture of x64, so I assumed it would have been picked up correctly, but it wasn't. So, I hard coded ALL the projects to a CPU Architecture of x64. I then received an error message about my interop assembly failing to load. My interop project, a C++/CLI project and has its configuration hard coded to x64 within the solution as that's the only thing we support.
Problem 2: CPU architecture ignored at compile time
At this point my interop assembly was failing to load with a "Bad image format exception," which suggests it's not being loaded as a 64-bit assembly. I did a NC reset but the tests still failed. I pulled up the generated interop and test assemblies and despite the NC CPU architecture being set to x64, both assemblies are compiled as AnyCPU. As a test, I replaced the NC-generated Interop.dll with the dll from my standard build output and re-ran the NC tests and all the tests passed.
Summary:
NC didn't autodetect the architecture correctly. Except my interop project which is compiled x64, each of my assemblies is compiled AnyCPU. Despite hard-coding the CPU architecture to x64 in NC, all the assemblies output by NC are compiled as AnyCPU which causes my other.dll, which is 64-bit only, to fail to load.
I'm still new enough to .NET that I don't know how the assemblies being compiled as AnyCPU instead of x64 interacts with DLL loading when a 64-bit DLL is required. I would think that it would be fine to compile an assembly as AnyCPU if it were being ran as x64, but perhaps that's not the case. Like I said, replacing the NC-generated AnyCPU compiled Interop dll with my standard x64-compiled interop dll allows the tests to pass.
Thank you again for all your help.
--Kaleb