1

次のコードを使用して、WMI を使用してディスク ドライブへの新しいメディアの挿入を検出しようとしました。しかし、DriveInfo.GetDrives でバックグラウンド スレッドでループを使用するようなマネージド ソリューションはありますか? これを行う最良の方法はどれですか?次のコードを試したときに、「ディスクがドライブにありません。ディスクを挿入してください」というダイアログが表示され、他の PC で中止、再試行、続行ボタンが表示されます。5 月のマシンでは正常に動作します。

private void DriveWatcher()
{
    try
    {
        var wqlEventQuery = new WqlEventQuery
            {
                EventClassName = "__InstanceModificationEvent",
                WithinInterval = new TimeSpan(0, 0, 1),
                Condition =
                    @"TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5"
            };

        var connectionOptions = new ConnectionOptions
            {
                EnablePrivileges = true,
                Authority = null,
                Authentication = AuthenticationLevel.Default
            };

        var managementScope = new ManagementScope("\\root\\CIMV2", connectionOptions);

        ManagementEventWatcher = new ManagementEventWatcher(managementScope, wqlEventQuery);
        ManagementEventWatcher.EventArrived += CdrEventArrived;
        ManagementEventWatcher.Start();
    }
    catch (ManagementException e)
    {
        MessageBox.Show(e.Message, e.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

private void CdrEventArrived(object sender, EventArrivedEventArgs e)
{
    var wmiDevice = (ManagementBaseObject) e.NewEvent["TargetInstance"];
    if (wmiDevice.Properties["VolumeName"].Value != null)
        GetDrives();
    else
        GetDrives();
}

private void GetDrives()
{
    if (InvokeRequired)
    {
        Invoke(new GetDrivesDelegate(GetDrives));
    }
    else
    {
        toolStripComboBoxDrives.Items.Clear();
        DriveInfo[] drives = DriveInfo.GetDrives();
        _drives = new Dictionary<string, DriveInfo>();
        int selectedIndex = 0;
        foreach (DriveInfo drive in drives)
        {
            if (drive.DriveType.Equals(DriveType.CDRom))
            {
                if (drive.IsReady)
                {
                    string name = string.Format("{0} ({1})", drive.VolumeLabel, drive.Name.Substring(0, 2));
                    int selectedDrive = toolStripComboBoxDrives.Items.Add(name);
                    _drives.Add(name, drive);
                    selectedIndex = selectedDrive;
                }
                else
                {
                    toolStripComboBoxDrives.Items.Add(drive.Name);
                    _drives.Add(drive.Name, drive);
                }
            }
        }
        toolStripComboBoxDrives.SelectedIndex = selectedIndex;
    }
}

基本的に私がやっていることは、Drive Watcher と呼ばれるフォーム読み込みイベントです。そのため、ディスクが挿入されると、準備ができたディスクが最初にコンボ ボックスに表示され、ユーザーはドライブを簡単に取り出すことができます。

4

3 に答える 3

2

これらのコードで試すことができます:

public void networkDevice()
{
    try
    {
        WqlEventQuery q = new WqlEventQuery();
        q.EventClassName = "__InstanceModificationEvent";
        q.WithinInterval = new TimeSpan(0, 0, 1);
        q.Condition = @"TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5";

        ConnectionOptions opt = new ConnectionOptions();
        opt.EnablePrivileges = true;
        opt.Authority = null;
        opt.Authentication = AuthenticationLevel.Default;
        //opt.Username = "Administrator";
        //opt.Password = "";
        ManagementScope scope = new ManagementScope("\\root\\CIMV2", opt);

        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, q);
        watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
        watcher.Start();
    }
    catch (ManagementException e)
    {
        Console.WriteLine(e.Message);
    }
}

void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    ManagementBaseObject wmiDevice = (ManagementBaseObject)e.NewEvent["TargetInstance"];
    string driveName = (string)wmiDevice["DeviceID"];
    Console.WriteLine(driveName);
    Console.WriteLine(wmiDevice.Properties["VolumeName"].Value);
    Console.WriteLine((string)wmiDevice["Name"]);
    if (wmiDevice.Properties["VolumeName"].Value != null)
        Console.WriteLine("CD has been inserted");
    else
        Console.WriteLine("CD has been ejected");
}

お使いのマシンで動作し、他のウィンドウ ベースのマシンでは動作しない場合は、そのマシンの WMI クラスを再構築/修復/再登録する必要があります。これはそれであなたを助けます。

于 2013-04-25T13:51:50.310 に答える
1

次のコードを参照してください。

foreach (DriveInfo drive in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.CDRom))  
    MessageBox.Show(drive.Name + " " + drive.IsReady.ToString());  

参照リンク:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/1ecb74cd-d193-40f5-9aa3-47a3c9adb4ea/

スタック リンク:

ディスクが DVD ドライブにあるかどうかの検出

于 2013-04-25T06:19:21.563 に答える