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

时间:2012-09-13 18:01:54

标签: .net visual-studio-2010 c++-cli mstest

我正在尝试在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.

所以我觉得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

0 个答案:

没有答案