我正在debugging的问题,.NET 4.0(WinForm,而不是WPF)应用程序在Windows XP上崩溃,当用户locking/解锁机器或用户点击ctrl-alt-delete,然后命中转义(不一定locking这个场景 – 但是他们可以selectlocking,调出任务pipe理器等)。 这是非常可重复的。
这与绘制ToolStripComboBox
。 这是在引擎盖下的一些gdiplus
例程中生成一个AccessViolationException
。
有几种不同的方式,我看到它的崩溃,但都在同一个区域绘制这个控制。 这是一个堆栈跟踪:
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at System.Drawing.SafeNativeMethods.Gdip.GdipFillRectangleI(HandleRef graphics, HandleRef brush, Int32 x, Int32 y, Int32 width, Int32 height) at System.Drawing.Graphics.FillRectangle(Brush brush, Int32 x, Int32 y, Int32 width, Int32 height) at System.Drawing.Graphics.FillRectangle(Brush brush, Rectangle rect) at System.Windows.Forms.ToolStripComboBox.ToolStripComboBoxControl.ToolStripComboBoxFlatComboAdapter.DrawFlatComboDropDown(ComboBox comboBox, Graphics g, Rectangle dropDownRect) at System.Windows.Forms.ComboBox.FlatComboAdapter.DrawFlatCombo(ComboBox comboBox, Graphics g) at System.Windows.Forms.ComboBox.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) ...
有没有人有关于如何解决这个问题的build议,或者机器locking/解锁或ctrl-alt-delete屏幕的重要内容是什么?
编辑:
我将其简化为一个简单的应用程序粘贴在下面,在XP专业版很好再现。 这简直就是我们所能得到的。 一切都是在UI线程上创build/操作的。
namespace Test { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } public class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, System.EventArgs e) { webBrowser2.Navigate("http://www.cnn.com"); } /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); this.webBrowser2 = new System.Windows.Forms.WebBrowser(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox(); this.toolStripContainer1.ContentPanel.SuspendLayout(); this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); this.toolStripContainer1.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.SuspendLayout(); // // toolStripContainer1 // this.toolStripContainer1.BottomToolStripPanelVisible = false; // // toolStripContainer1.ContentPanel // this.toolStripContainer1.ContentPanel.Controls.Add(this.webBrowser2); this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(555, 268); this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; this.toolStripContainer1.LeftToolStripPanelVisible = false; this.toolStripContainer1.Location = new System.Drawing.Point(0, 0); this.toolStripContainer1.Name = "toolStripContainer1"; this.toolStripContainer1.RightToolStripPanelVisible = false; this.toolStripContainer1.Size = new System.Drawing.Size(555, 296); this.toolStripContainer1.TabIndex = 1; this.toolStripContainer1.Text = "toolStripContainer1"; // // toolStripContainer1.TopToolStripPanel // this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1); // // webBrowser2 // this.webBrowser2.Dock = System.Windows.Forms.DockStyle.Fill; this.webBrowser2.Location = new System.Drawing.Point(0, 0); this.webBrowser2.MinimumSize = new System.Drawing.Size(20, 20); this.webBrowser2.Name = "webBrowser2"; this.webBrowser2.Size = new System.Drawing.Size(555, 268); this.webBrowser2.TabIndex = 0; // // toolStrip1 // this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None; this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripLabel1, this.toolStripComboBox1}); this.toolStrip1.Location = new System.Drawing.Point(3, 0); this.toolStrip1.Name = "toolStrip1"; this.toolStrip1.Size = new System.Drawing.Size(173, 28); this.toolStrip1.TabIndex = 0; // // toolStripLabel1 // this.toolStripLabel1.Name = "toolStripLabel1"; this.toolStripLabel1.Size = new System.Drawing.Size(38, 25); this.toolStripLabel1.Text = "blah"; // // toolStripComboBox1 // this.toolStripComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.toolStripComboBox1.Items.AddRange(new object[] { "ab", "c", "d", "e", "f"}); this.toolStripComboBox1.Name = "toolStripComboBox1"; this.toolStripComboBox1.Size = new System.Drawing.Size(121, 28); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(555, 296); this.Controls.Add(this.toolStripContainer1); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.toolStripContainer1.ContentPanel.ResumeLayout(false); this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false); this.toolStripContainer1.TopToolStripPanel.PerformLayout(); this.toolStripContainer1.ResumeLayout(false); this.toolStripContainer1.PerformLayout(); this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); this.ResumeLayout(false); } #endregion private ToolStripContainer toolStripContainer1; private ToolStrip toolStrip1; private ToolStripLabel toolStripLabel1; private ToolStripComboBox toolStripComboBox1; private WebBrowser webBrowser2; } }
编辑2:
我无法在Windows XP媒体中心版,只有XP专业版到目前为止重现这一点。
我们已经有一段时间了这个问题。 相同的调用堆栈,并发生在用户执行ctrl-alt-del和转义时。 情况有点不同,它发生在我们的WinForm应用程序,它是WinForm和WPF控件的混合。 在应用程序中,我们有一个在ElementHost中托管的WPF UserControl,并且当这个组件处于浮动窗口中时,将鼠标悬停在重新绘制的WinForm控件上,并锁定和解锁屏幕,引发AccessViolationException,应用程序崩溃。 我应该提到我们也在使用Infragistics UltraDockWorkspace。
我们还没有找到一个解决方案,但是当最近使用MS源代码进行调试时,我注意到引发异常的方法(在System.Drawing中的Graphics.cs中)的注释:
/// <devdoc> /// GDI+ will return a 'generic error' with specific win32 last error codes when /// a terminal server session has been closed, minimized, etc... We don't want /// to throw when this happens, so we'll guard against this by looking at the /// 'last win32 error code' and checking to see if it is either 1) access denied /// or 2) proc not found and then ignore it. /// /// The problem is that when you lock the machine, the secure desktop is enabled and /// rendering fails which is expected (since the app doesn't have permission to draw /// on the secure desktop). Not sure if there's anything you can do, short of catching /// the desktop switch message and absorbing all the exceptions that get thrown while /// it's the secure desktop. /// </devdoc> private void CheckErrorStatus(int status) { if (status != SafeNativeMethods.Gdip.Ok) { // Generic error from GDI+ can be GenericError or Win32Error. if (status == SafeNativeMethods.Gdip.GenericError || status == SafeNativeMethods.Gdip.Win32Error) { int error = Marshal.GetLastWin32Error(); if (error == SafeNativeMethods.ERROR_ACCESS_DENIED || error == SafeNativeMethods.ERROR_PROC_NOT_FOUND || //here, we'll check to see if we are in a term. session... (((UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_REMOTESESSION) & 0x00000001) != 0) && (error == 0))) { return; } } //legitimate error, throw our status exception throw SafeNativeMethods.Gdip.StatusException(status); } }
从我所了解的情况来看,由于在安全桌面模式下呈现,AccessViolationException应该被抑制,但是在某些情况下,这个异常正在被传播。
对不起,我不能提供解决方案,但希望这个信息是有用的。