方法一: 使用FileSystemWatcher https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
public void ListOpticalDiscDrivesAndWatchRootDirectory()
{
var drives = DriveInfo.GetDrives();
foreach (var drive in drives)
{
if (drive.IsReady && drive.DriveType == DriveType.CDRom)
{
var rootDirectory = drive.RootDirectory.ToString();
Console.WriteLine(rootDirectory);
Watch(rootDirectory);
}
}
}
private void Watch(string path)
{
var watcher = new FileSystemWatcher
{
Path = path,
NotifyFilter = NotifyFilters.Attributes |
NotifyFilters.CreationTime |
NotifyFilters.DirectoryName |
NotifyFilters.FileName |
NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.Security |
NotifyFilters.Size,
Filter = "*.*",
EnableRaisingEvents = true
};
watcher.Changed += new FileSystemEventHandler(OnChanged);
}
private void OnChanged(object source, FileSystemEventArgs e)
{
Console.WriteLine("Something changed!");
}
方法2: 使用WMI https://msdn.microsoft.com/en-us/library/aa394582(v=vs.85).aspx
有一个代码项目示例 https://www.codeproject.com/articles/42212/wmi-and-file-system-monitoring(VBScript) 描述如何使用 WMI 进行文件系统监控。我在下面的 C# 代码片段中使用了该示例中的查询:
using System;
using System.Management;
public class OpticalDriveWatcher
{
private ManagementEventWatcher _wmiWatcher = new ManagementEventWatcher();
public ManagementEventWatcher WmiWatcher
{
get { return _wmiWatcher; }
}
private void OnWmiEventReceived(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("WMI event!");
}
public void WatchWithWMI(string path)
{
string queryString = "Select * From __InstanceOperationEvent "
+ "WITHIN 2 "
+ "WHERE TargetInstance ISA 'CIM_DataFile' "
+ $"And TargetInstance.Drive='{path}'";
WqlEventQuery wmiQuery = new WqlEventQuery(queryString);
WmiWatcher.Query = wmiQuery;
WmiWatcher.Start();
}
}
问题是CIM_数据文件 https://msdn.microsoft.com/en-us/library/aa387236(v=vs.85).aspx仅返回本地固定磁盘上的文件实例。您可以按如下方式调用它
var detector = new OpticalDriveDetector();
var drive = "I:"; //You could get the optical drive you want to watch with DriveInfo as described in approach 1
detector.WatchWithWMI(drive);
detector.WmiWatcher.EventArrived += detector.OnWmiEventReceived;
当我使用 DVD-RAM 进行测试时,这两种方法都对我来说效果很好。