C# 监控端口';s USB,没有WinForm,只有控制台应用程序

C# 监控端口';s USB,没有WinForm,只有控制台应用程序,c#,events,console-application,C#,Events,Console Application,我在学C#,我需要帮助,拜托。 我的问题:如何知道USB磁盘是否已安装/卸载? 我找到了WndProd的答案 const int WM_DEVICECHANGE = 0x0219; const int DBT_DEVICEARRIVAL = 0x8000; const int DBT_DEVICEREMOVECOMPLETE = 0x8004; [StructLayout(LayoutKind.Sequential)]

我在学C#,我需要帮助,拜托。 我的问题:如何知道USB磁盘是否已安装/卸载? 我找到了WndProd的答案

    const int WM_DEVICECHANGE           = 0x0219;
    const int DBT_DEVICEARRIVAL         = 0x8000; 
    const int DBT_DEVICEREMOVECOMPLETE  = 0x8004;

    [StructLayout(LayoutKind.Sequential)]
    public struct DEV_BROADCAST_HDR
    {
        public int dbch_size;
        public int dbch_devicetype;
        public int dbch_reserved;
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_DEVICECHANGE)
        {
            int EventCode = m.WParam.ToInt32();
            Log(string.Format("WM_DEVICECHANGE. Код={0}", EventCode));

            switch (EventCode)
            {
                case DBT_DEVICEARRIVAL:
                {
                    Log("Добавление устройства");
                    break;
                }
                case DBT_DEVICEREMOVECOMPLETE:
                {
                    Log("Удаление устройства");
                    break;
                }
            }
        }
        base.WndProc (ref m);

    }
这个版本呢

public class WMIReceiveEvent
    {
        public WMIReceiveEvent()
        {
            try
            {
                WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent");

                ManagementEventWatcher watcher = new ManagementEventWatcher(query);
                Console.WriteLine("Waiting for an event...");

                watcher.EventArrived += new EventArrivedEventHandler(HandleEvent);

                // Start listening for events
                watcher.Start();

                // Do something while waiting for events
                System.Threading.Thread.Sleep(20000);

                // Stop listening for events
                //watcher.Stop();
                //return;
            }
            catch (ManagementException err)
            {

            }
        }

        private void HandleEvent(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Win32_DeviceChangeEvent event occurred.   "+ e.NewEvent.ClassPath.ClassName.ToString());
            Console.WriteLine("2_Win32_DeviceChangeEvent event occurred.   " + e.NewEvent.Properties.ToString());
            Console.ReadLine();
        }            

    }
但是我想要不带WinForm的DBT_DEVICEARRIVALDBT_DeviceMoveComplete版本。因为WndProc需要System.Windows.Form和类必须是继承者“:Form
对于WMIReceiveEvent,这不是我任务的最佳解决方案。

为此编写控制台应用程序的问题在于它没有消息循环(至少,不是默认情况下;您必须自己编写)


更简单的解决方案是创建一个Windows窗体项目,但不显示任何窗体。实际上,您将创建一个不显示任何用户界面的“后台”应用程序。WinForms应用程序自动为您提供消息泵,允许您捕获感兴趣的消息。

根据应用程序的要求,您不妨进行轮询。构建一个循环,检查所有可能的驱动器号,如

System.IO.Directory.Exists(driveLetter)

并将其与现有的驱动器号数组或结构或其他内容进行比较。一旦它们不同,就创建一个事件


这将是一个简单的方法,尽管在性能方面没有那么出色。但正如我所说的,这取决于您的需求。

您可以使用
NativeWindow
而不是
Form
,并且仍然使用
WndProc(ref Message msg)
。 它实际上是一种无形的形式,参见示例:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyMessageHandler : NativeWindow
{
    private event EventHandler<MyEventArgs> messageReceived;
    public event EventHandler<MyEventArgs> MessageReceived
    {
        add
        {
            if (messageReceived == null || !messageReceived.GetInvocationList().Contains(value))
                messageReceived += value;
        }
        remove
        {
            messageReceived -= value;
        }
    }

    public MyMessageHandler()
    {
        var cp = new CreateParams();
        CreateHandle(cp);
    }

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message msg)
    {
        var handler = messageReceived;
        if (handler != null)
            handler(this, new MyEventArgs(msg));

        base.WndProc(ref msg);
    }
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand,Name=“FullTrust”)]
公共类MyMessageHandler:NativeWindow
{
接收到私有事件EventHandler message;
已收到公共事件EventHandler消息
{
添加
{
如果(messageReceived==null | |!messageReceived.GetInvocationList()包含(值))
messageReceived+=值;
}
去除
{
messageReceived-=值;
}
}
公共MyMessageHandler()
{
var cp=新的CreateParams();
CreateHandle(cp);
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand,Name=“FullTrust”)]
受保护的覆盖无效WndProc(参考消息消息消息)
{
var handler=messageReceived;
if(处理程序!=null)
handler(这是新的MyEventArgs(msg));
基本WndProc(参考msg);
}
}

非常感谢您的快速回复。以及如何自己编写消息循环?或者如果是继承者,如何在ConsoleApp中使用“后台”应用程序:表单?非常感谢你。你的例子很有趣,很容易实现。但我想获得信息系统方面的经验。但不幸的是,网络上的培训材料很少,非经验人士可以理解。我真的希望这种技术能起作用,但不幸的是,控制台应用程序只接收少数消息事件,而WM_DEVICECHANGE不是其中之一。