2

For example, I can catch the Delete event for various files in a folder tree, but how would I go about determining which user caused the delete to happen?

I couldn't find anything obvious in the MSDN documentation for FileSystemWatcher, so maybe it is just not possible. I'd be curious if there is a solution however.

Ash
  • 60,973
  • 31
  • 151
  • 169

3 Answers3

4

This isn't currently possible with the current implementations of the FileSystemWatcher as it does not receive this type of information when a file is deleted, or anything about a file changes.

Scott Dorman
  • 42,236
  • 12
  • 79
  • 110
  • Do you know if this is possible at all in a .NET application? Or would I need to delve into the Win API? – Ash Aug 17 '09 at 04:43
  • @Ash: You would need to use Win32 API calls, if it's possible at all. I'm not sure which APIs you would need to use, but you will end up essentially writing your own version of a file system watcher. – Scott Dorman Aug 17 '09 at 14:10
4

It is possible using Folder Auditing (folder Properties > Security > Advanced Options > Auditing) and then looking up the Security Event Log after the FileSystemWatcher event fires.

string GetUser(string path) {
    object nowDate = Now;
    GetUser = "Unknown";
    Threading.Thread.Sleep(1000);
    // # Search user in the security event log
    object secLog = new EventLog("Security", EVENTLOGSERVER);
    EventLogEntry entry;
    for (int i = (secLog.Entries.Count - 1); (i <= Math.Max((secLog.Entries.Count - 1500), 0)); i = (i + -1)) {
        entry = secLog.Entries(i);
        if (IsValidEntry(path, nowDate, entry)) {
            GetUser = entry.ReplacementStrings(11);
            break;
        }
    }
}

bool IsValidEntry(string path, DateTime nowDate, EventLogEntry entry) {
    return ((entry.EntryType == EventLogEntryType.SuccessAudit) 
        && ((entry.InstanceId == 560) || (entry.InstanceId == 564)) 
        && !entry.UserName.EndsWith("SYSTEM")
        && (Math.Abs(nowDate.Subtract(entry.TimeGenerated).TotalSeconds <= 20) 
        && (entry.ReplacementStrings.GetUpperBound(0) >= 11) 
        && (entry.ReplacementStrings(2).Length >= 4) 
        && path.EndsWith(entry.ReplacementStrings(2).Substring(4)));
}
Ignacio Calvo
  • 754
  • 9
  • 22
1

It doesn't seem like there's any functionality built into .NET that can help you with that, but with the help of the function NetFileGetInfo in Netapi32.dll, it should be possible.

Take a look at this thread where the user dave4dl has posted a code sample that shows how to do it.

René
  • 9,880
  • 4
  • 43
  • 49