特定文件类型的文件系统过滤器驱动程序

File system filter driver for specific file types

我需要检测何时以任何方式在整个 windows 文件系统中访问两种文件类型中的任何一种。

据我所知,在不导致操作系统严重减速的情况下执行此操作的唯一方法是创建文件系统过滤驱动程序?

基本上我需要做的就是复制所有打开的 doc(x) 文件和 pdf。我决定采用这种方法,因为要么在 C# 中使用文件监视器,要么对整个驱动器无效。

我的问题有两个,有没有更简单的方法,其次我将如何简单地复制每个访问的 doc(x)/pdf 文件?

该解决方案需要可以使用我们当前生成的包进行部署。

更新

我要对文件系统观察器进行基准测试,在与这里的人讨论后我认为它可能是可以接受的,我担心的是我需要监视将发生下载的公共用户目录( 所以 "C:\Users\SomeUser*" 以及 outlook 临时文件夹。

您将需要创建一个文件系统监视器。这是一个代码示例,它将监视对 docx 文件的更改。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Permissions;

namespace filewatchtest
{
    class Program
    {
        static void Main(string[] args)
        {
            Run();
        }

        [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
        public static void Run()
        {
            string[] args = System.Environment.GetCommandLineArgs();

            // if directory not specified then end program
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: filewatchtest.exe directory");
                return;
            }

            // create a new fileSystemWatcher and set its properties
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = args[1];

            // set the notify filters
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;

            // set the file extension filter
            watcher.Filter = "*.docx";

            // add event handlers
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.Deleted += new FileSystemEventHandler(OnChanged);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);

            // bengin watching
            watcher.EnableRaisingEvents = true;

            // wait for the user to quit the program
            Console.WriteLine("Plress q to quit the program");
            while (Console.Read()!='q');


        }

        static void OnRenamed(object sender, RenamedEventArgs e)
        {
            Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
        }

        static void OnChanged(object sender, FileSystemEventArgs e)
        {            
            Console.WriteLine("File:" + e.FullPath + " " + e.ChangeType);
        }



    }
}

我认为在读取时创建副本会导致很多问题。例如:病毒扫描程序。考虑以下因素:

  1. 我打开文件"test.pdf"
  2. 您的程序创建 "test_copy.pdf"
  3. 病毒扫描程序检测到新文件并检查(读取)"test_copy.pdf"
  4. 您的程序检测到读取访问,并创建 "test_copy_copy.pdf"
  5. 病毒扫描程序...

现在您当然可以创建具有不同扩展名的副本来防止这种情况发生,但仍然会对文件进行很多 READ 操作。我有时会打开一个文件 10 次,只是因为我不小心关闭了它,或者我想重新检查刚刚阅读的内容。现在你有 10 份了?

我肯定会同意 Hans Passant 关于在 change/create 上创建副本的建议。根据定义,这种情况很少发生,因为您总是需要打开它来更改它,但不必在打开它时更改它。

第二个问题是检测对文件的读取。现在使用 docx,您可以检查隐藏文件的创建,例如“~$_____.docx”,但这对 PDF 不起作用。也像你提到的,你将不得不检查整个磁盘。没有其他办法了。如果文件可以在任何文件夹中,则必须检查所有文件夹。在服务中创建 docxPDF 文件的内部列表可能会更快,但由于您必须以设定的时间间隔再次循环遍历每个文件,这取决于系统上有多少文件。

因此,如果您真的需要检查 read access,文件系统驱动程序就足够了。但是由于它会在每次文件访问时调用,因此导致问题或系统缓慢将是一个主要问题。

如果您仍然想要,请查看此 File System Filter Driver Tutorial 以了解如何操作。就个人而言,我不会去那里。

根据我在评论中读到的内容,文件系统观察器可能会很好用。我不确定 Search Everything 是否使用了一个,但如果使用了,我看不出有任何影响。

另一个选项可能是 ETW - Windows Event Tracing as used by Process Monitor。即使有数百万的变化,我也几乎察觉不到影响。

我想按照 Hans Passant 的建议使用卷影副本,Alpha Volume Shadow Copies 可能是提供支持的合适库。

结论:可能不需要过滤器驱动程序,它可以让您远离其他问题,尽管我承认 分层存储管理系统 的描述可能符合您的方法,考虑到上传存储作为硬盘之后的下一个层次。