简体   繁体   English

检测驱动器c中的DVD插入的最佳方法#

[英]Best way to detect dvd insertion in drive c#

I tried using WMI to detect new media insertion in Disk Drive using following code. 我尝试使用WMI使用以下代码检测磁盘驱动器中的新媒体插入。 But is there managed solution like using loop in background thread with DriveInfo.GetDrives? 但是有没有管理解决方案,比如在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? 当我尝试下面的代码时,我得到'磁盘不在驱动器中请插入磁盘'对话框中止,重试并继续在其他PC上按钮? 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;
    }
}

Basically what i'm doing is on form load event called Drive Watcher. 基本上我正在做的是名为Drive Watcher的表单加载事件。 So when disk is inserted ready disk will be listed first in combo box and user can eject the drive easily. 因此,当插入磁盘时,就会在组合框中首先列出就绪磁盘,用户可以轻松弹出磁盘。

you can try with these code : 你可以试试这些代码:

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");
}

if it works on your machine and does not work on any other window based machine, then you have to rebuild/repair/re-register that machine's WMI classes. 如果它在您的机器上工作并且不能在任何其他基于窗口的机器上工作,那么您必须重建/修复/重新注册该机器的WMI类。 This will help you in that. 将有助于你。

Refer Following Code: 参考以下代码:

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

Referance Link: Referance链接:

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

Stack Link: Stack Link:

Detecting if disc is in DVD drive 检测光盘是否在DVD驱动器中

I'm going with following solution. 我将采用以下解决方案。 It's 100% managed solution. 这是100%管理的解决方案。 It's not using WMI and works great. 它没有使用WMI并且效果很好。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM