2012-09-02 61 views
3

我正在調試一個問題,當用戶鎖定/解鎖機器或用戶點擊ctrl時,.NET 4.0(WinForm,非WPF)應用程序在Windows XP上崩潰-alt-delete,然後點擊轉義(不一定在這種情況下鎖定 - 但他們可以選擇鎖定,調出任務管理器等)。這是非常可重複的。訪問衝突繪畫ToolStripComboBox與XP專業版的WebBrowser控件

這與繪畫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) 
... 

有沒有人對如何解決這個問題,或者什麼機器鎖定/解鎖或的顯著CTRL-ALT-刪除畫面是建議?

編輯:

我煮下來到粘貼下面一個簡單的應用,它是在XP專業版漂亮的重現性。這非常香草 - 我們可以得到的很簡單。一切都是在UI線程上創建/操作的。

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[] { 
            "a b", 
            "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 Media Center Edition的複製本,只有XP專業版爲止。

+0

這是由SystemEvents類引發的問題。它是在錯誤的線程上發射它的事件。 –

+0

@HansPassant我粘貼了顯示問題的應用程序的源代碼。一切都在UI線程上完成。 – jglouie

+0

驚人的錯誤。是否需要Web瀏覽器控件?如果需要工具條和瀏覽器,這會很奇怪。 – usr

回答

1

我們已經有一段時間了現在這個問題。相同的調用堆棧,並在用戶執行ctrl-alt-del和escape時發生。 場景有點不同,它發生在我們的WinForm應用程序中,它是WinForm和WPF控件的混合。在應用程序中,我們有一個WPF UserControl託管在ElementHost中,並且當此組件處於浮動窗口中時,將鼠標懸停在正在重繪的WinForm控件上,並且屏幕被鎖定和解鎖,將引發AccessViolationException並導致應用程序崩潰。我應該提到我們也在使用Infragistics UltraDockWorkspace。

我們還沒有找到一個解決辦法,但最近調試使用MS源的時候,我注意到在其中異常被拋出(在Graphics.cs在System.Drawing中)的方法,此評論:

  /// <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應該被壓制在這裏,但是在某些情況下,這個異常正在被傳播。

對不起,我不能提供解決方案,但希望這個信息是有用的。

+0

謝謝 - 非常有見地 – jglouie