在驱动器 c# 中检测 dvd 插入的最佳方法 [英] Best way to detect dvd insertion in drive c#

查看:20
本文介绍了在驱动器 c# 中检测 dvd 插入的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 WMI 使用以下代码检测磁盘驱动器中的新媒体插入.但是是否有托管解决方案,例如在带有 DriveInfo.GetDrives 的后台线程中使用循环?哪种方法最好?当我尝试以下代码时,我收到磁盘不在驱动器中,请插入磁盘"对话框并在其他电脑上中止、重试和继续按钮?在可能机器上它工作正常.

I tried using WMI to detect new media insertion in Disk Drive using following code. But is there managed solution like using loop in background thread with DriveInfo.GetDrives? Which is best way to do this? I'm getting 'Disk is not in the drive please insert disk' dialog with abort, retry and continue button on other pc when i tried the following code? On may machine it works fine.

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 的表单加载事件上.因此,当磁盘插入时,准备好的磁盘将首先列在组合框中,用户可以轻松弹出驱动器.

Basically what i'm doing is on form load event called Drive Watcher. So when disk is inserted ready disk will be listed first in combo box and user can eject the drive easily.

推荐答案

我将采用以下解决方案.这是 100% 托管解决方案.它不使用 WMI 并且运行良好.

I'm going with following solution. It's 100% managed solution. It's not using WMI and works great.

internal class DriveWatcher
{
    public delegate void OpticalDiskArrivedEventHandler(Object sender, OpticalDiskArrivedEventArgs e);

    /// <summary>
    ///     Gets or sets the time, in seconds, before the drive watcher checks for new media insertion relative to the last occurance of check.
    /// </summary>
    public int Interval = 1;

    private Timer _driveTimer;

    private Dictionary<string, bool> _drives;

    private bool _haveDisk;

    /// <summary>
    ///     Occurs when a new optical disk is inserted or ejected.
    /// </summary>
    public event OpticalDiskArrivedEventHandler OpticalDiskArrived;

    private void OnOpticalDiskArrived(OpticalDiskArrivedEventArgs e)
    {
        OpticalDiskArrivedEventHandler handler = OpticalDiskArrived;
        if (handler != null) handler(this, e);
    }

    public void Start()
    {
        _drives = new Dictionary<string, bool>();
        foreach (
            DriveInfo drive in
                DriveInfo.GetDrives().Where(driveInfo => driveInfo.DriveType.Equals(DriveType.CDRom)))
        {
            _drives.Add(drive.Name, drive.IsReady);
        }
        _driveTimer = new Timer {Interval = Interval*1000};
        _driveTimer.Elapsed += DriveTimerOnElapsed;
        _driveTimer.Start();
    }

    public void Stop()
    {
        if (_driveTimer != null)
        {
            _driveTimer.Stop();
            _driveTimer.Dispose();
        }
    }

    private void DriveTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
    {
        if (!_haveDisk)
        {
            try
            {
                _haveDisk = true;
                foreach (DriveInfo drive in from drive in DriveInfo.GetDrives()
                                            where drive.DriveType.Equals(DriveType.CDRom)
                                            where _drives.ContainsKey(drive.Name)
                                            where !_drives[drive.Name].Equals(drive.IsReady)
                                            select drive)
                {
                    _drives[drive.Name] = drive.IsReady;
                    OnOpticalDiskArrived(new OpticalDiskArrivedEventArgs {Drive = drive});
                }
            }
            catch (Exception exception)
            {
                Debug.Write(exception.Message);
            }
            finally
            {
                _haveDisk = false;
            }
        }
    }
}

internal class OpticalDiskArrivedEventArgs : EventArgs
{
    public DriveInfo Drive;
}

您可以按如下方式使用它.

You can use this as follows.

var driveWatcher = new DriveWatcher();
driveWatcher.OpticalDiskArrived += DriveWatcherOnOpticalDiskArrived;
driveWatcher.Start();

private void DriveWatcherOnOpticalDiskArrived(object sender, OpticalDiskArrivedEventArgs e)
{
    MessageBox.Show(e.Drive.Name);
}

这篇关于在驱动器 c# 中检测 dvd 插入的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆