我的公司最终将我们的开发团队从Windows XP升级到Windows 7 64位计算机,我刚刚在新环境中发现了现有代码的奇怪错误。有问题的项目引用了一个用于与我们的文档图像管理系统交互的COM库。任何初始化此API的Library类实例的尝试现在都会抛出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:
在处理我的示例项目时,我能够确认以下内容:
总而言之,如果我们在面向.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组件类似的问题,如果有的话,是否有办法防止或忽略这些类型的错误在调试时,因为错误只是由于在调试器中运行而产生的。