NetworkInterface.GetAllNetworkInterfaces приводит к тому, что AppDomain.UnhandledException прекращает работу в Windows XP Embedded. - PullRequest
2 голосов
/ 17 ноября 2009

У меня есть приложение, предназначенное для настольных ОС (XP, Vista, Win7), а также для мобильных устройств под управлением Windows XP Embedded. Все платформы работают с полной .Net Framework, , а не Compact Framework. Приложение использует событие AppDomain.UnhandledException для обнаружения и регистрации любых фатальных ошибок приложения. Ничего необычного там нет, и он отлично работает - по крайней мере, на настольных ОС.

В другом месте приложения есть фрагмент кода, который вызывает метод NetworkInterface.GetAllNetworkInterfaces для получения списка сетевых карт на компьютере. В Windows XP Embedded - но не в настольных ОС - после вызова этого метода событие AppDomain.UnhandledException больше не срабатывает при возникновении необработанных исключений. Вместо этого приложение просто вылетает, даже не отображая стандартное диалоговое окно сбоя .Net.

Это известная ошибка, или я что-то не так делаю? Кто-нибудь знает обходной путь для этого?

Вот пример приложения, которое воспроизводит проблему. Этот пример написан на WinForms, но та же проблема возникает и в WPF.

using System;
using System.Net.NetworkInformation;
using System.Threading;
using System.Windows.Forms;

namespace BugDemo
{
    public class BugDemoForm : Form
    {
        /// <summary>
        /// This is the entry point of the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            Application.Run(new BugDemoForm());
        }

        /// <summary>
        /// Sets up a simple form with two buttons for reproducing the bug.
        /// </summary>
        public BugDemoForm()
        {
            Padding = new Padding(15);
            Width = 400;
            int halfHeight = (ClientRectangle.Height / 2) - Padding.Vertical;

            Button exceptionButton = new Button();
            exceptionButton.Dock = DockStyle.Top;
            exceptionButton.Height = halfHeight;
            exceptionButton.Text = "Test the AppDomain.UnhandledException method";
            exceptionButton.Click += exceptionButton_Click;
            Controls.Add(exceptionButton);

            Button networkInterfacesButton = new Button();
            networkInterfacesButton.Dock = DockStyle.Bottom;
            networkInterfacesButton.Height = halfHeight;
            networkInterfacesButton.Text = "Call the NetworkInterface.GetAllNetworkInterfaces method";
            networkInterfacesButton.Click += networkInterfacesButton_Click;
            Controls.Add(networkInterfacesButton);
        }

        /// <summary>
        /// Throws an exception on a background thread. 
        /// This will cause the <see cref="AppDomain.UnhandledException"/> event to fire.
        /// </summary>
        private static void exceptionButton_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(
                delegate(object state)
                {
                    throw new ApplicationException();
                });
        }

        /// <summary>
        /// Calls the <see cref="NetworkInterface.GetAllNetworkInterfaces"/> method.
        /// Once this method is called, the <see cref="AppDomain.UnhandledException"/> event
        /// will no longer fire.
        /// </summary>
        private static void networkInterfacesButton_Click(object sender, EventArgs e)
        {
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            MessageBox.Show("There are " + nics.Length + " network interfaces on this machine.\n\n"
                + "Now that the NetworkInterface.GetAllNetworkInterfaces method has been called, "
                + "the AppDomain.UnhandledException event will no longer fire when running on "
                + "Windows XP Embedded.");
        }

        /// <summary>
        /// Fires whenever an unhandled exception occurs on a background thread.
        /// However, once the <see cref="NetworkInterface.GetAllNetworkInterfaces"/> method has been
        /// called, this event no longer fires.
        /// </summary>
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show("The AppDomain.UnhandledException event fired successfully.\n"
                + "The app will now crash, as expected.");
        }
    }
}
...