9

我是 C# 新手,必须用 C# 开发一个 Windows 窗体应用程序。此应用程序应跟踪以下内容。

  • 监控外部和内部的 CD/DVD 驱动器。
  • 监控 CD/DVD 驱动器上创建、修改和删除的文件。

我可以RegisterNotification通过跟踪方法WM_DEVICECHANGE中的消息来获取 CD/DVD 驱动器插入的系统通知WndProc

上述实现让我知道何时将新设备连接到 PC。

我面临的问题是如何跟踪 CD/DVD 上发生的文件更改(写入/修改)。一种选择是将 CD/DVD 中的文件作为后台作业进行轮询。但是,这将是最后的选择。

我发现IMAPI我们可以通过它写入 CD/DVD,但我只需要监视文件更改以进行审计。

请指出我如何在我的程序中接收 CD/DVD 通知上的文件更改的正确方向?

我已经尝试过FileSystemWatcher,但它似乎不适用于 CD/DVD 驱动器。

2018 年 2 月 7 日更新:

我能找到的另一种方法是通过WMI附加到WMI Events. 我发现了一个问题Best way to detect dvd insertion in drive c#也可以回答。我想知道在 WMI 中检测 DVD 文件系统修改是否可行,以及是否有专家可以共享相同的查询。我希望如果Arshad能够在这方面提供帮助。

4

1 回答 1

8

方法 1:使用FileSystemWatcher

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

有一个代码项目示例(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_DataFile只返回本地固定磁盘上的文件实例。你可以这样称呼它

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 进行测试时,这两种方法对我来说都很好。

于 2018-02-08T20:04:45.613 回答