程序集无法在MSTest下加载(EEFileLoadException)

dsh*_*pak 7 .net mstest c++-cli visual-studio-2010

我试图在MSTest场景中解决EEFileLoadException,该场景结合了托管代码和本机代码.

我的应用程序包含几十个DLL:一些本机(非托管)C++,一些C++/CLI和一些C#.所有DLL都在同一目录中.在正常操作中,主可执行文件是本机C++.其中一个本机DLL(让我们称之为Native.DLL)链接到C++/CLI DLL,后者又引用其中一个C#程序集,一切正常.

现在我正在尝试用MSTest编写测试.代码结构由C#单元测试组成,它引用了C++/CLI程序集,该程序集调用前面提到的Native.DLL.但是,当我尝试运行测试时,我会在Native.DLL调用它使用的第一个C++/CLI程序集时获得EEFileLoadException.

我已经使用Fusion日志查看器来尝试调试程序集加载问题.这是日志中的精简摘录:

*** Assembly Binder Log Entry  (9/12/2012 @ 2:51:14 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\VS2010\Common7\IDE\QTAgent32.exe

LOG: Appbase = file:///C:/VS2010/Common7/IDE/
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\VS2010\Common7\IDE\QTAgent32.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/VS2010/Common7/IDE/My.Managed.Assembly.DLL
(...)
LOG: All probing URLs attempted and failed.
Run Code Online (Sandbox Code Playgroud)

因此我很清楚,AppBase已被设置为QTAgent32.exe的位置,并且它在那里搜索托管程序集,而不是在我所有DLL实际所在的目录中搜索.它没有问题找到所有单元测试直接引用的程序集,并且找到非托管DLL没有问题,但是当非托管DLL尝试加载其他托管程序集时它会失败(尽管将引用移动到单元测试表明这是一个红色的鲱鱼;请参阅我的说明在"我试过的东西"下面.

我正在Visual Studio 2010中完成所有这些.单元测试主要是生成代码; 它们实际上是用SpecFlow编写的验收测试.

我的问题,如果还不清楚的是:为什么我的程序集无法加载,我该如何解决?

这是我已经尝试过的:

  • 禁用部署(没有这个,我甚至无法做到这一点)
  • 将我的应用程序的路径添加到LocalTestRun.testrunco​​nfig(作为"要加载的程序集的根文件夹"和"运行测试时要使用的文件夹")
  • 添加AppDomain.CurrentDomain.SetData("APPBASE", TheDirectoryThatMyDLLsAreIn);到我的单元测试中
  • 从我的单元测试代码中引用托管程序集,并在调用本机C++之前向其中添加虚拟调用,以尝试预加载程序集,以便在C++需要它们时它们已经存在.这有一个令人惊讶的结果:当JIT编译调用我的C++/CLI程序集的方法时,会发生相同的EEFileLoadException.
  • 为问题程序集添加了强名称.这没有效果.
  • 添加了无法加载到GAC的程序集.执行此操作后,程序集加载仍然失败,但没有Fusion日志解释原因,并且测试结果包含消息" The same bind was seen before, and was failed with hr = 0x80070002.".我认为无论如何使用GAC都不是长期可接受的解决方案.

这是运行测试时MSTest提供的错误:

Test method MyTestAssembly.MyTestMethod threw exception: 
System.TypeInitializationException: The type initializer for '<Module>' threw an exception. ---> <CrtImplementationDetails>.ModuleLoadExceptionHandlerException: A nested exception occurred after the primary exception that caused the C++ module to fail to load.
 ---> System.TypeInitializationException: The type initializer for '<Module>' threw an exception. ---> <CrtImplementationDetails>.ModuleLoadException: The C++ module failed to load during process initialization.
 ---> System.IO.FileNotFoundException: Could not load file or assembly 'MyNamespace.MyCPlusPlusCLIModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1478252538103a9d' or one of its dependencies. The system cannot find the file specified.Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\VS2010\Common7\IDE\QTAgent32.exe
Run Code Online (Sandbox Code Playgroud)