Мониторинг USB порта без WinForm, только консольное приложение - PullRequest
0 голосов
/ 08 марта 2012

Я изучаю 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();
        }            

    }

, но мне нужна версия для DBT_DEVICEARRIVAL и DBT_DEVICEREMOVECOMPLETE без WinForm,Потому что для WndProc нужно System.Windows.Form , а Class должен быть преемником ": Form ", а для WMIReceiveEvent не лучшее решение для моей задачи.

Ответы [ 3 ]

2 голосов
/ 05 июня 2012

Вы можете использовать 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);
    }
}
1 голос
/ 08 марта 2012

Проблема написания консольного приложения для этого заключается в том, что в нем нет цикла сообщений (по крайней мере, не по умолчанию; вам придется написать свое).

Более простое решение - создать проект Windows Forms, но просто не показывать никаких форм. По сути, вы будете создавать «фоновое» приложение, которое не отображает никакого пользовательского интерфейса. Приложения WinForms обеспечивают автоматическую отправку сообщений, позволяя вам перехватывать интересующие вас сообщения.

0 голосов
/ 08 марта 2012

В зависимости от требований вашего приложения вы можете также сделать опрос. Вы строите цикл, проверяя все возможные буквы дисков, такие как

System.IO.Directory.Exists (DriveLetter);

и сравните его с существующим массивом букв или структурой диска Создайте событие, как только они будут другими.

Это был бы простой способ, хотя и не столь фантастический с точки зрения производительности. Но, как я уже сказал, это зависит от ваших требований.

...