5

特定の名前の USB スティックがコンピューターに接続されているかどうかを確認する小さなスクリプトを作成しましたが、このスクリプトの周りにサービスを作成して、スティックが接続されているかどうかを監視したいと考えています。最初に、ファイルウォッチャーでこれを行い、スティックにファイルを作成しようとしましたが、スティックをPCから取り外して再接続すると、ファイルウォッチャーはそれを認識しません。次のスクリプトは、スティックが接続されているかどうかを 1 回チェックしますが、この DriveInfo.GetDrive 関数をループするスクリプトが必要です。この関数の周りに 10 秒のタイマー ループを構築するのが最善の方法なのか、それとも .NET Framework に取り外し可能なデバイス用のウォッチャー クラスがあるのか​​はわかりません。スクリプトは次のとおりです。

public static void Main()
{
    Run();
}

public static void Run()
{                     
    var drives = DriveInfo.GetDrives()
        .Where(drive => drive.IsReady && drive.DriveType == DriveType.Removable);
    if (drives.Count() > 0)
    {
        foreach (var drive in drives)
        {
           if (drive.VolumeLabel == "TESTLABEL") Console.WriteLine("USB Stick is plugged in");
        }
    }
}
4

1 に答える 1

9

を使用して (USB) イベントにフックできますManagementEventWatcher

を使用するこのきちんとした答えを言い換えるLinqPadの実例:Win32_DeviceChangeEvent

// using System.Management;
// reference System.Management.dll
void Main()
{    
    using(var control = new USBControl()){
        Console.ReadLine();//block - depends on usage in a Windows (NT) Service, WinForms/Console/Xaml-App, library
    }
}

class USBControl : IDisposable
    {
        // used for monitoring plugging and unplugging of USB devices.
        private ManagementEventWatcher watcherAttach;
        private ManagementEventWatcher watcherDetach;

        public USBControl()
        {
            // Add USB plugged event watching
            watcherAttach = new ManagementEventWatcher();
            watcherAttach.EventArrived += Attaching;
            watcherAttach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
            watcherAttach.Start();

            // Add USB unplugged event watching
            watcherDetach = new ManagementEventWatcher();
            watcherDetach.EventArrived += Detaching;
            watcherDetach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
            watcherDetach.Start();
        }

        public void Dispose()
        {
            watcherAttach.Stop();
            watcherDetach.Stop();
            //you may want to yield or Thread.Sleep
            watcherAttach.Dispose();
            watcherDetach.Dispose();
            //you may want to yield or Thread.Sleep
        }

        void Attaching(object sender, EventArrivedEventArgs e)
        {
            if(sender!=watcherAttach)return;
            e.Dump("Attaching");
        }

        void Detaching(object sender, EventArrivedEventArgs e)
        {
            if(sender!=watcherDetach)return;
            e.Dump("Detaching");
        }

        ~USBControl()
        {
            this.Dispose();// for ease of readability I left out the complete Dispose pattern
        }
    }

USB スティックを接続すると、7 つの接続 (または接続解除) イベントを受け取ります。好きなように取り付け/取り外し方法をカスタマイズします。ブロッキングの部分は、必要に応じて読者に任せます。Windows サービスを使用する場合は、まったくブロックする必要はありません。

于 2013-08-06T16:47:14.333 に答える