Обнаружение «сетевого кабеля отключен» в Compact Framework - PullRequest
5 голосов
/ 09 октября 2009

Я прошел через все ответы на вопросы о переполнении стека, и ни Google, ни Bing не показали мне никакой любви. Мне нужно знать, когда сетевой кабель был подключен или отключен на устройстве Windows CE, предпочтительно из приложения Compact Framework.

1 Ответ

3 голосов
/ 09 октября 2009

Я понимаю, что отвечаю на свой вопрос здесь, но на самом деле это был вопрос, заданный по электронной почте, и я потратил довольно много времени, чтобы найти ответ, поэтому я публикую его здесь.

Таким образом, общий ответ для того, как это обнаружено, заключается в том, что вам нужно вызвать драйвер NDIS через IOCTL и сказать ему, что вы заинтересованы в уведомлениях. Это делается с помощью значения IOCTL_NDISUIO_REQUEST_NOTIFICATION (в документах сказано, что это не поддерживается в WinMo, но документы не верны). Конечно, получать уведомления не так просто - вы не просто получите хороший обратный вызов. Вместо этого вам нужно развернуть очередь сообщений точка-точка и отправить ее в вызов IOCTL вместе с маской, какие конкретные уведомления вы хотите. Затем, когда что-то изменится (например, тянется кабель), вы получите структуру NDISUIO_DEVICE_NOTIFICATION (опять же, MSDN неправильно говорит, что это только CE) в очереди, которую затем можно проанализировать, чтобы найти адаптер, который было событие и каково точное событие.

С точки зрения управляемого кода это на самом деле много кода, который нужно написать - CreateFile, чтобы открыть NDIS, все API очередей, структуры для уведомлений и т. Д. К счастью, я уже шел по этому пути и уже добавил его в Smart Device Framework. Поэтому, если вы используете SDF, получение уведомлений выглядит следующим образом:

public partial class TestForm : Form
{
    public TestForm()
    {
        InitializeComponent();

        this.Disposed += new EventHandler(TestForm_Disposed);

        AdapterStatusMonitor.NDISMonitor.AdapterNotification += 
            new AdapterNotificationEventHandler(NDISMonitor_AdapterNotification);
        AdapterStatusMonitor.NDISMonitor.StartStatusMonitoring();
    }

    void TestForm_Disposed(object sender, EventArgs e)
    {
        AdapterStatusMonitor.NDISMonitor.StopStatusMonitoring();
    }

    void NDISMonitor_AdapterNotification(object sender, 
                                         AdapterNotificationArgs e)
    {
        string @event = string.Empty;

        switch (e.NotificationType)
        {
            case NdisNotificationType.NdisMediaConnect:
                @event = "Media Connected";
                break;
            case NdisNotificationType.NdisMediaDisconnect:
                @event = "Media Disconnected";
                break;
            case NdisNotificationType.NdisResetStart:
                @event = "Resetting";
                break;
            case NdisNotificationType.NdisResetEnd:
                @event = "Done resetting";
                break;
            case NdisNotificationType.NdisUnbind:
                @event = "Unbind";
                break;
            case NdisNotificationType.NdisBind:
                @event = "Bind";
                break;
            default:
                return;
        }

        if (this.InvokeRequired)
        {
            this.Invoke(new EventHandler(delegate
            {
                eventList.Items.Add(string.Format(
                                    "Adapter '{0}' {1}", e.AdapterName, @event));
            }));
        }
        else
        {
            eventList.Items.Add(string.Format(
                                "Adapter '{0}' {1}", e.AdapterName, @event));
        }
    }
}
...