1

我收到用户说我的应用程序崩溃了,他在事件查看器中看到了这个:

Framework Version: v4.0.30319    
Description: The process was terminated due to an unhandled exception.
    Exception Info: System.AccessViolationException
    Stack:
       at System.Drawing.SafeNativeMethods+Gdip.GdipDrawRectangleI(System.Runtime.InteropServices.HandleRef, System.Runtime.InteropServices.HandleRef, Int32, Int32, Int32, Int32)
       at System.Drawing.Graphics.DrawRectangle(System.Drawing.Pen, Int32, Int32, Int32, Int32)
       at System.Windows.Forms.ToolStripTextBox+ToolStripTextBoxControl.WmNCPaint(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.ToolStripTextBox+ToolStripTextBoxControl.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
       at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr, IntPtr, Int32, IntPtr, IntPtr)
       at System.Windows.Forms.NativeWindow.DefWndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Form.DefWndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.ScrollableControl.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Form.WndProc(System.Windows.Forms.Message ByRef)
       at DeskandArchive.MainWindow.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
       at System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG ByRef, System.Runtime.InteropServices.HandleRef, Int32, Int32, Int32)
       at System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, Int32, Int32)
       at System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
       at System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
       at System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
       at A.cc1462b28845fccfe3634174d36bc619a.ce1b648a1c328cbefe2529fb98bf21b8c()

据我通过互联网搜索,并且我可以从中读到,还包括这样一个事实,即如果我的代码崩溃它应该显示对话框以报告用户没有看到的错误,我得出的结论是这是一个错误.NET 框架绘制工具条。

我说得对吗?有什么方法可以解决这个问题吗?我已经阅读了重新安装 .NET 框架的建议,但大多数人报告说它没有帮助?

4

1 回答 1

5

崩溃的不是 ToolStrip,而是 GDI+。GDI+ 是一大块在 .NET 出现之前就已经存在的非托管代码,System.Drawing 是带有包装类的命名空间。与此堆栈跟踪中使用的 Graphics 类一样。

让 GDI+ 崩溃是非常罕见的,.NET 包装类非常擅长防止错误的参数传递给 GDI+ 的函数。获得这样的 AccessViolation 需要破坏 GDI+ 使用的堆。堆被非托管代码中的指针错误损坏。这可能是您的代码,值得注意的是您正在覆盖 WndProc()。但更典型的是,它是一些将自身注入您的流程的应用程序。要么是故意的,比如病毒扫描程序,要么是意外地像使用 OpenFileDialog 时加载的 shell 扩展处理程序。这样的扩展也可以使用 GDI+,这很常见,或者只是有一个错误的指针,可以在任何地方喷洒垃圾。

您永远不会从托管堆栈跟踪中发现,损坏早在 GDI+ 崩溃之前就已完成。这使得诊断堆损坏错误变得异常困难,这也是 Java 和 .NET 成为非常流行的平台的重要原因。当您无法完全复制用户的运行时环境时,这将变得不可能。像这样的错误几乎总是以“无复制”的方式关闭,就像您将它提交给 Microsoft 时仅使用堆栈跟踪作为证据一样。追求重现场景取决于您,但请注意您将很难处理它。告诉用户最好的办法是使用另一台机器,或者通过卸载不必要的或有风险的程序让她的机器再次稳定。特别是外壳扩展。

于 2012-10-27T13:00:20.197 回答