Find out username(who) modified file in C#
I cant remember where I found this code but its an alternative to using pInvoke which I think is a bit overkill for this task. Use the FileSystemWatcher
to watch the folder and when an event fires you can work out which user made the file change using this code:
private string GetSpecificFileProperties(string file, params int[] indexes)
{
string fileName = Path.GetFileName(file);
string folderName = Path.GetDirectoryName(file);
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder objFolder;
objFolder = shell.NameSpace(folderName);
StringBuilder sb = new StringBuilder();
foreach (Shell32.FolderItem2 item in objFolder.Items())
{
if (fileName == item.Name)
{
for (int i = 0; i < indexes.Length; i++)
{
sb.Append(objFolder.GetDetailsOf(item, indexes[i]) + ",");
}
break;
}
}
string result = sb.ToString().Trim();
//Protection for no results causing an exception on the `SubString` method
if (result.Length == 0)
{
return string.Empty;
}
return result.Substring(0, result.Length - 1);
}
Shell32 is a reference to the DLL: Microsoft Shell Controls And Automation - its a COM reference
Here is some example's of how you call the method:
string Type = GetSpecificFileProperties(filePath, 2);
string ObjectKind = GetSpecificFileProperties(filePath, 11);
DateTime CreatedDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 4));
DateTime LastModifiedDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 3));
DateTime LastAccessDate = Convert.ToDateTime(GetSpecificFileProperties(filePath, 5));
string LastUser = GetSpecificFileProperties(filePath, 10);
string ComputerName = GetSpecificFileProperties(filePath, 53);
string FileSize = GetSpecificFileProperties(filePath, 1);
Or get multiple comma separated properties together:
string SizeTypeAndLastModDate = GetSpecificFileProperties(filePath, new int[] {1, 2, 3});
Note: This solution has been tested on Windows 7 and Windows 10. It wont work unless running in a STA as per Exception when using Shell32 to get File extended properties and you will see the following error:
Unable to cast COM object of type 'Shell32.ShellClass' to interface type 'Shell32.IShellDispatch6'
Programmatically determine user who last modified file on Windows?
I don't think you'll be able to monitor this from C# directly. Not without the help of the host operating system anyway. Windows and NTFS allow you to audit a particular directory and log the accesses in the Security event log for the host machine (so the server hosting the share would have to audit, not the client).
From KB310399 - How to audit user access of files, folders, and printers in Windows XP
Auditing User Access of Files, Folders, and Printers
The audit log appears in the Security log in Event Viewer. To enable this feature:
- Click Start, click Control Panel, click Performance and Maintenance, and then click Administrative Tools.
- Double-click Local Security Policy.
- In the left pane, double-click Local Policies to expand it.
- In the left pane, click Audit Policy to display the individual policy settings in the right pane.
- Double-click Audit object access.
- To audit successful access of specified files, folders and printers, select the Success check box.
- To audit unsuccessful access to these objects, select the Failure check box.
- To enable auditing of both, select both check boxes.
- Click OK.
Specifying Files, Folders, and Printers to Audit
After you enable auditing, you can specify the files, folders, and printers that you want audited. To do so:
- In Windows Explorer, locate the file or folder you want to audit. To audit a printer, locate it by clicking Start, and then clicking Printers and Faxes.
- Right-click the file, folder, or printer that you want to audit, and then click Properties.
- Click the Security tab, and then click Advanced.
- Click the Auditing tab, and then click Add.
- In the Enter the object name to select box, type the name of the user or group whose access you want to audit. You can browse the computer for names by clicking Advanced, and then clicking Find Now in the Select User or Group dialog box.
- Click OK.
- Select the Successful or Failed check boxes for the actions you want to audit, and then click OK.
- Click OK, and then click OK.
The process is similar for the server operating systems and Windows Vista/Windows 7. If you go this route, you can have the C# program read the event log (See EventLog
class) to look for the data you want.
Note: Starting with vista you must be and (UAC elevated if needed) administrator to read them from code.
Finding the user who modified the shared drive folder files
I have got the fix to that,
It can be achieved using the ObjectSecurity Class of .NET. In that we can use the GetOwner.
It fetches the owner of the file who has modified / created a file.
This is the piece of code which would help:
string owner = System.IO.File.GetAccessControl(e.FullPath).GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
Console.WriteLine(owner);
How to find out who modified a shared directories and files in C# or Powershell?
The best way to do this is to enable advanced file auditing on the servers you need this information on. If that isn't an option (it can get quite inefficient on servers with high disk IO), you can try using FileSystemWatcher
to get the same results. Here is an example of how to do that!
Get Username of an Accesed File
From My last program ( 2 week ago) - I was asked to audit change in files ( also the user name)
the Solution was by filesystemwatcher and after an event -> goto the Event Log of windows and bu Xpath search - To find which user made the action.
public static EventUnit DisplayEventAndLogInformation(string fileToSearch, DateTime actionTime)
{
StringBuilder sb = new StringBuilder();
const string queryString = @"<QueryList>
<Query Id=""0"" Path=""Security"">
<Select Path=""Security"">*</Select>
</Query>
</QueryList>";
EventLogQuery eventsQuery = new EventLogQuery("Security", PathType.LogName, queryString);
eventsQuery.ReverseDirection = true;
EventLogReader logReader = new EventLogReader(eventsQuery);
EventUnit e = new EventUnit();
bool isStop = false;
for (EventRecord eventInstance = logReader.ReadEvent(); null != eventInstance; eventInstance = logReader.ReadEvent())
{
foreach (var VARIABLE in eventInstance.Properties)
if (VARIABLE.Value.ToString().ToLower().Contains(fileToSearch.ToLower()) && actionTime.ToString("d/M/yyyy HH:mm:ss") == eventInstance.TimeCreated.Value.ToString("d/M/yyyy HH:mm:ss"))
{
foreach (var VARIABLE2 in eventInstance.Properties) sb.AppendLine(VARIABLE2.Value.ToString());
e.Message = sb.ToString();
e.User = (eventInstance.Properties.Count > 1) ? eventInstance.Properties[1].Value.ToString() : "n/a";
e.File = fileToSearch;
isStop = true;
break;
}
if (isStop) break;
try
{
// Console.WriteLine("Description: {0}", eventInstance.FormatDescription());
}
catch (Exception e2)
{
}
}
return e;
}
Related Topics
C# Create/Modify/Read .Xlsx Files
Metadata Were Not Loaded Using Metadatatype
Write to Windows Application Event Log Without Event Source Registration
How to Correctly Prefix a Word with "A" and "An"
Checking If a String Array Contains a Value, and If So, Getting Its Position
How Expensive Is the Lock Statement
How to Change the Font Color of a Disabled Textbox
Does Distinct() Method Keep Original Ordering of Sequence Intact
Is Enabling Double Escaping Dangerous
C# Entity-Framework: How to Combine a .Find and .Include on a Model Object
How to Check If Object Already Exists in a List
Asp .Net MVC Disable Client Side Validation at Per-Field Level