Обработать событие системных папок в Windows - PullRequest
8 голосов
/ 20 сентября 2011

Я пишу код на C #, и мне нужно определить, была ли определенная папка в моей файловой системе Windows открыта во время работы приложения. Есть ли способ сделать это? WinAPI может быть?

Ответы [ 6 ]

2 голосов
/ 23 сентября 2011

Есть три вещи API, которые я думаю, вы должны проверить:

FindFirstChangeNotification () http://msdn.microsoft.com/en-us/library/aa364417%28VS.85%29.aspx Это дает вам дескриптор, который вы можете подождать и использовать для поиска изменений в файле в определенном файле, каталоге или дереве каталогов. Он не сообщит вам, когда просматривается каталог, но сообщит, когда файл будет сохранен, переименован и т. Д. И т. Д.

SetWindowsHookEx () http://msdn.microsoft.com/en-us/library/ms644990%28v=VS.85%29.aspx Вы можете настроить его так, чтобы он получал обратный вызов при любом количестве событий - на самом деле я весьма уверен, что вы МОЖЕТЕ получить этот обратный вызов при открытии каталога, но это, вероятно, будет чрезмерно трудным, потому что вы будете перехватывать сообщения в окно исследователя. Таким образом, вы будете перезагружаться во время отладки.

Windows Shells http://msdn.microsoft.com/en-us/library/bb776778%28v=VS.85%29.aspx Если это не было достаточно болезненно, вы можете попробовать написать программу-оболочку.

Если вы пытаетесь написать руткит, я полагаю, вы не хотите, чтобы я испортил вам детали. Если вы НЕ пытаетесь написать руткит, я советую вам посмотреть его внимательно. Существуют руткиты с открытым исходным кодом, и все они в основном должны отслеживать доступ к файлам таким образом, чтобы скрыть их от пользователя / ОС.

1 голос
/ 14 октября 2011

Перейти с расширениями оболочки Windows.Вы можете использовать Shell Namespace Extensions, чтобы создать «виртуальную» папку, которой нет (или скрывает настоящую), например, GAC (C: \ Windows \ assembly)

Вот несколько примеровкодирования Shell Extension в .Net 4.0 .

A Обработчик столбцов сообщит вам, когда папка «открыта», и даже позволит вам предоставить дополнительные данные для каждого изфайлы (новые столбцы сведений).

0 голосов
/ 30 декабря 2011

Вы можете использовать LastAccessProperty FileSystemInfo. Проблема, однако, в том, что его можно кэшировать.

FileSystemInfo: http://msdn.microsoft.com/en-us/library/975xhcs9.aspx

LastAccessTime Свойство: http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.lastaccesstimeutc.aspx

Как уже отмечалось, это можно предварительно кэшировать.

"Значение свойства LastAccessTimeUtc предварительно кэшируется, если текущий экземпляр объекта FileSystemInfo был возвращен любым из следующих методов DirectoryInfo:

GetDirectories

GetFiles

GetFileSystemInfos

EnumerateDirectories

EnumerateFiles

EnumerateFileSystemInfos

Чтобы получить последнее значение, вызовите метод Refresh. "

Поэтому вызовите метод Refresh, но он все еще может не обновляться из-за кэширования значения в Windows. (Это в соответствии с msdn doc "FileSystemInfo.Refresh берет снимок файла из текущей файловой системы. Обновление не может исправить лежащую в основе файловую систему, даже если файловая система возвращает неверную или устаревшую информацию. Это может происходить на платформах, таких как Windows 98 . "- ссылка: http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.refresh.aspx

0 голосов
/ 18 октября 2011

Я думаю, что единственный способ, которым вы можете надежно достичь этого, - отслеживать текущие процессы и внимательно следить за новыми экземплярами Explorer.exe и / или новыми порожденными потоками Explorer.exe (параметр «Запускать каждое окно в отдельном процессе») мешает здесь).

Признаюсь, у меня нет ни малейшего понятия о том, как это кодировать, но это то, что я искал.

0 голосов
/ 20 сентября 2011

Самая близкая вещь, о которой я могу подумать и которая может быть вам полезна, - это использование статического класса Directory. Он предоставляет методы для определения времени последнего доступа к файлу или каталогу. Вы можете настроить BackgroundWorker для отслеживания доступа к каталогу в течение указанного интервала. Отслеживайте начало и конец интервала с помощью DateTime, и если время последнего доступа падает между ними, то вы можете использовать событие ProgressChanged BackgroundWorker's для уведомления приложения.

 BackgroundWorker folderWorker = new BackgroundWorker();
 folderWorker.WorkerReportsProgress = true;
 folderWorker.WorkerSupportsCancellation = true;
 folderWorker.DoWork += FolderWorker_DoWork;
 folderWorker.ProgressChanged += FolderWorker_ProgressChanged;

 folderWorker.RunWorkerAsync();

 void FolderWorker_DoWork(object sender, DoWorkEventArgs e)
 {
      BackgroundWorker worker = (BackgroundWorker)sender;

      while(!worker.CancellationPending)
      {
           DateTime lastAccess = Directory.GetLastAccessTime(DIRECTORY_PATH);

           //Check to see if lastAccess falls between the last time the loop started
           //and came to end.
           if(/*your check*/)
           {
                object state;  //Modify this if you need to send back data.
                worker.ReportProgress(0, state);
           }
      }
 }

 void FolderWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
 {
      //Take action here from the worker.ReportProgress being invoked.
 }
0 голосов
/ 20 сентября 2011

Проверьте FileSystemWatcher класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...