在Compact Framework中检测"网络电缆未插入"

cta*_*cke 5 networking compact-framework ndis windows-ce

我已经浏览了所有Stack Overflow答案搜索结果,Google或Bing都没有向我展示任何爱情.我需要知道何时在Windows CE设备上连接或断开网络电缆,最好是从Compact Framework应用程序.

cta*_*cke 3

我意识到我在这里回答了我自己的问题,但这实际上是通过电子邮件提出的问题,而且我实际上花了很长时间才找到答案,所以我将其发布在这里。

因此,关于如何检测到这一点的一般答案是,您必须通过 IOCTL 调用 NDIS 驱动程序并告诉它您对通知感兴趣。这是通过IOCTL_NDISUIO_REQUEST_NOTIFICATION值完成的(文档说 WinMo 不支持此操作,但文档是错误的)。当然,接收通知并不是那么简单 - 您不仅仅是得到一些不错的回电。相反,您必须启动一个点对点消息队列并将其发送到 IOCTL 调用,以及您想要的特定通知的掩码。然后,当发生变化时(例如电缆被拉动),您将在队列中获得一个NDISUIO_DEVICE_NOTIFICATION结构(MSDN 再次错误地表示这是仅限 CE 的),然后您可以解析该结构以查找发生该事件的适配器以及发生了什么事件。确切的事件是。

从托管代码的角度来看,这实际上需要编写大量代码 - CreateFile 来打开 NDIS、所有排队 API、通知结构等。幸运的是,我已经沿着这条路走了,并且添加了已将其添加到智能设备框架中。因此,如果您使用 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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)