特定文件类型的文件系统筛选器驱动程序

时间:2015-01-22 21:02:01

标签: c# c++ windows file-io

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

据我了解,在不造成操作系统严重减速的情况下执行此操作的唯一方法是创建文件系统过滤器驱动程序吗?

基本上我需要做的就是获取任何doc(x)文件和打开的pdf文件的副本。我决定使用这种方法,因为它或者使用C#中的文件监视器,这对整个驱动器都没有效果。

我的问题有两个方面,是否有一种更简单的方法;其次,如果只是获取每个doc(x)/ pdf文件的副本,我将如何进行访问?

解决方案需要与我们目前正在生产的软件包一起部署。

更新

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

3 个答案:

答案 0 :(得分:2)

您需要创建一个文件系统观察程序。这是一个代码示例,它将监视对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 :(得分:2)

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

  1. 我打开文件“test.pdf”
  2. 您的程序会创建“test_copy.pdf”
  3. 病毒扫描程序检测到新文件并检查(读取)“test_copy.pdf”
  4. 您的程序检测到读取权限,并创建“test_copy_copy.pdf”
  5. 病毒扫描程序......
  6. 现在您可以创建具有不同扩展名的副本以防止这种情况发生,但仍然会对文件执行大量READ操作。我有时打开一个文件10次,只是因为我意外关闭它或者我想重新检查我刚读过的东西。现在你将有10份?

    我肯定会考虑Hans Passant关于创建变更/创建副本的建议。根据定义,这种情况发生的情况要少得多,因为你总是需要打开它来改变它,但是当你打开它时不必改变它。

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

    因此,如果您确实需要检查read access,那么您只需要一个文件系统驱动程序。但是,因为它会在每次访问文件时调用,导致问题或系统速度变慢都会引起市长的关注。

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

答案 2 :(得分:1)

从我在评论中看到的内容,文件系统观察器可能会运行良好。我不确定Search Everything是否使用了一个,但如果确实如此,我就注意不到任何影响。

ETW - Windows Event Tracing使用的另一个选项可能是Process Monitor。即使有数百万的变化,我也几乎没有注意到这种影响。

我想使用Hans Passant提出的卷影副本,Alpha Volume Shadow Copies可能是一个提供支持的合适库。

结论:可能不需要过滤器驱动程序,让您远离其他问题,但我承认分层存储管理系统的描述可能与您的方法相符,将上传存储区视为硬盘后的下一层次。