Программно определить, кто последний изменял файл в Windows? - PullRequest
12 голосов
/ 07 декабря 2011

Мне было поручено написать простую утилиту командной строки на C #, которая будет отслеживать каталог на сервере, к которому несколько пользователей будут обращаться для копирования / вырезания / вставки / просмотра данных. Я использовал FileSystemWatcher , чтобы сделать это, но ему не хватает пары функций.

Можно ли определить пользователя или хотя бы имя компьютера , откуда файл доступен или изменен?

(Примечание: это не обязательно должно быть с FileSystemWatcher, я ищу ЛЮБОЙ способ сделать это.)

Ответы [ 2 ]

7 голосов
/ 07 декабря 2011

Не думаю, что вы сможете контролировать это из C # напрямую.В любом случае, не без помощи операционной системы.Windows и NTFS позволяют проводить аудит определенного каталога и регистрировать доступы в журнале событий безопасности для хост-компьютера (так что сервер, на котором размещается общий ресурс, должен проводить аудит, а не клиент).

С KB310399 - Как проверять пользовательский доступ к файлам, папкам и принтерам в Windows XP

Аудит доступа пользователей к файлам, папкам и принтерам

Журнал аудита отображается вжурнал безопасности в Event Viewer.Чтобы включить эту функцию:

  1. Нажмите кнопку Пуск, выберите Панель управления, нажмите кнопку Производительность и обслуживание, а затем нажмите Администрирование.
  2. Дважды щелкните Локальная политика безопасности.
  3. На левой панели дважды щелкните Локальные политики, чтобы развернуть ее.
  4. На левой панели щелкните Политика аудита, чтобы отобразить отдельные параметры политики на правой панели.
  5. Дважды щелкните Аудитдоступ к объектам.
  6. Чтобы проверить успешный доступ к указанным файлам, папкам и принтерам, установите флажок Успех.
  7. Чтобы проверить неуспешный доступ к этим объектам, установите флажок Сбой.
  8. Чтобы включить аудит обоих, установите оба флажка.
  9. Нажмите ОК.

Указание файлов, папок и принтеров для аудита

После включенияАудит, вы можете указать файлы, папки и принтеры, которые вы хотите проверять.Для этого:

  1. В проводнике Windows найдите файл или папку, которые вы хотите проверить.Чтобы провести аудит принтера, найдите его, нажав кнопку «Пуск», а затем нажмите «Принтеры и факсы».
  2. Щелкните правой кнопкой мыши файл, папку или принтер, который вы хотите проверить, и выберите Свойства.
  3. Перейдите на вкладку «Безопасность» и нажмите «Дополнительно».
  4. Перейдите на вкладку «Аудит» и нажмите кнопку «Добавить».
  5. В поле «Введите имя объекта для выбора» введите имя пользователя илигруппа, доступ к которой вы хотите проверить.Чтобы просмотреть имена компьютеров, нажмите «Дополнительно», а затем нажмите «Найти сейчас» в диалоговом окне «Выбор пользователя или группы».
  6. Нажмите «ОК».
  7. Установите флажки «Успешно» или «Сбой» для действий.Вы хотите провести аудит, а затем нажмите кнопку ОК.
  8. Нажмите кнопку ОК, а затем нажмите кнопку ОК.

Процесс аналогичен для серверных операционных систем и Windows Vista / Windows7. Если вы пойдете по этому пути, вы можете заставить программу C # читать журнал событий (см. EventLog класс), чтобы найти нужные данные.

Примечание:Начиная с Vista, вы должны быть и (UAC повышены, если необходимо) администратором, чтобы читать их из кода.

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

Убедитесь, что WMI установлен или включен на вашем ПК, также обязательно добавьте ссылку на System.Management и System.Management.Instrumentation.Существует также графический интерфейс приложения для сценариев C # и VB WMI, который можно загрузить для запуска и тестирования запросов WMI, а также для Google.Поскольку я работаю в Министерстве обороны, есть некоторые вещи, которые я могу получить отсюда в отношении Интернета, другие вещи заблокированы, поэтому, пожалуйста, прости меня, если я не публикую определенные веб-ссылки.что-то, чтобы вы начали

    ManagementScope mgtScope = new ManagementScope("\\\\ComputerName\\root\\cimv2");
    // you could also replace the username in the select with * to query all objects
    ObjectQuery objQuery = new ObjectQuery("SELECT username FROM Win32_ComputerSystem");

    ManagementObjectSearcher srcSearcher = new ManagementObjectSearcher(mgtScope, objQuery);

    ManagementObjectCollection colCollection = srcSearcher.Get();

    foreach (ManagementObject curObjCurObject in colCollection)
    {

        Console.WriteLine(curObjCurObject["username"].ToString());
    } 

  //if you want ot get the name of the machine that changed it once it gets into that  Event change the query to look like this. I just tested this locally and it does work 

    ManagementObjectSearcher mosQuery = new ManagementObjectSearcher("SELECT * FROM Win32_Process WHERE ProcessId = " + Process.GetCurrentProcess().Id.ToString());
    ManagementObjectCollection queryCollection1 = mosQuery.Get();
    foreach (ManagementObject manObject in queryCollection1)
    {
        Console.WriteLine("Name : " + manObject["name"].ToString());
        Console.WriteLine("Version : " + manObject["version"].ToString());
        Console.WriteLine("Manufacturer : " + manObject["Manufacturer"].ToString());
        Console.WriteLine("Computer Name : " + manObject["csname"].ToString());
        Console.WriteLine("Windows Directory : " + manObject["WindowsDirectory"].ToString());
    }  
...