工具条崩溃

时间:2012-10-27 12:02:56

标签: c# .net winforms crash

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

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()

据我浏览互联网,我可以从中读到,还包括如果我的代码崩溃它应该显示对话框来报告用户没看到的错误,我得出结论,这是在绘制Toolstrip时.NET框架中的一个错误。

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

1 个答案:

答案 0 :(得分:5)

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

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

你永远不会从托管堆栈跟踪中发现损坏是在GDI +崩溃之前很久就完成的。这使得诊断堆损坏错误非常困难,这也是Java和.NET成为非常流行的平台的一个重要原因。当您无法完全复制用户的运行时环境时,就变得不可能了。像这样的bug几乎总是以“no repro”关闭,就像你将它提交给Microsoft而只有堆栈跟踪作为证据一样。你应该追求一个重复的场景,但要注意你将很难用它。告诉用户的最好的事情是使用另一台机器或通过卸载不必要或有风险的程序再次使其机器稳定。特别是shell扩展。