访问冲突绘画ToolStripComboBox与XP Pro上的WebBrowser控件

我正在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应该被抑制,但是在某些情况下,这个异常正在被传播。

对不起,我不能提供解决方案,但希望这个信息是有用的。