VS2010(及更高版本)中的 SEHException 但仅适用于 Windows 7 上的 .NET4 或更高版本

tch*_*ist 5 debugging .net-4.0 windows-7

我的公司最终将我们的开发团队从 Windows XP 升级到了 Windows 7 64 位计算机,我刚刚发现新环境中现有代码的一个奇怪错误。有问题的项目引用了一个 COM 库,该库用于与我们的文档图像管理系统进行交互。任何初始化此 API 的库类实例的尝试现在都会抛出 SEHException。返回的错误代码没有提供信息。这是我为测试此问题而编写的精简示例项目的完整异常:

System.Runtime.InteropServices.SEHException was caught
  ErrorCode=-2147467259
  HResult=-2147467259
  Message=External component has thrown an exception.
  Source=FileNetTestLib
  StackTrace:
       at FileNetTestLib.Library.Logon() in C:\Projects\Tests\SEHException\FileNetTestLib\Library.vb:line 4
       at SEHException.Form1.btnLogIn_Click(Object sender, EventArgs e) in C:\Projects\Tests\SEHException\SEHException\Form1.vb:line 7
  InnerException: 
Run Code Online (Sandbox Code Playgroud)

在使用我的示例项目时,我能够确认以下内容:

  • 异常仅在调试时发生;不调试运行不会抛出任何异常
  • 在 Windows XP 上调试时不会发生异常(在两台 Win7 和两台 XP 计算机上尝试)
  • 当我们将目标框架更改为低于 .NET 4 的任何内容时,不会发生异常。它只发生在 .NET4 或更高版本上。

总而言之,如果我们在面向 .NET4 或更高版本的 Windows 7 上进行调试,则会发生错误。如果我们改变这些因素中的任何一个,它就不会发生。

在研究这一点时,我发现 .NET4 改变了它的安全模型,以处理从非托管代码抛出的异常。乍一看,这可能与问题有关,但从我到目前为止所学到的知识来看,这些变化只影响 SEHExceptions 的一个子集,显然不是我得到的,因为 (1) 我能够抓住在 try...catch 块中的 SEHException,其中 .NET 中的更改导致受影响的异常(损坏的状态异常)根本不会被 .NET 捕获,除非您对代码或配置文件进行了某些更改(我没有做这些更改)并已确认我的项目中不存在)和 (2) 问题仅在 Windows 7 下发生在我身上,我没有发现任何表明 .NET4 中的这些更改是特定于 Win7 的。

仅供参考,我没有 32 位版本的 Win7,所以我无法确认问题是否特定于 Win7 64 位或一般的 Win7。我正在将项目编译为 x86,因为由于 COM 组件,我无法将其编译为 x64。我也在 VS 2013 和 VS 2010 上尝试过这个,并且在两者上都得到了相同的结果。

由于问题仅在调试时发生,我检查了哪些异常我允许调试器中断(希望它被选中,我可以取消选中它以使调试器忽略它)并且 SEHExeption 未选中(在 Debug|Exceptions 下)。我还检查了 VS 中的调试选项,并且未选中“异常跨越 AppDomain 或托管/本机边界时中断”。改变其中任何一个都没有任何区别。

我还尝试初始化一个完全不同的 COM 组件(在本例中为 ImageMagick),以确保任何 COM 组件都没有发生错误,但我没有遇到任何问题。我即将联系给我造成问题的 COM 组件的供应商,但我想知道是否有其他人遇到过其他 COM 组件的任何类似问题,如果有,是否有办法防止或忽略这些类型的错误调试时,因为错误似乎只是由于在调试器中运行而产生的。