How can i get user who deleted file? - c#

I need to know which user deleted file in filesystem from c# code.
Only one idea is to use audit, but it seem to be very slow...

You can use the FileSystemWatcher.Deleted event to capture deletes happening on the filesystem.
Depending on the application, you may at that point also be able to find out what user caused this event to occur (it is not part of FileSystemEventArgs).

I don't know if this can be retrieved from the filsystem, but one possible way is to use av FileSystemWatcher object to trigger an event on Deleted. The downside is that you need to have the watcher application running all the time. One upside is that you can monitor just a spesific folder if that's feasible.

Related

C# Monitor File Activity

I need to monitor a file for changes and see exactly where it has been modified.
It seems like I can't use FileSystemWatcher as I only get notified that a file has been modified but I can't know exactly what changed, and storing copies of the file to do a diff after the event is raised is not feasible since the file is really big.
I would like to implement something like what SysInternals have on their Process Monitor software, that tells us, for a WriteFile event, the modified part of the file given an offset and length.
I read that there is a Windows API that does this, but I couldn't find anything on how or where to start implementing it on a .net 3.5 application.
From what I have investigated, the .NET platform provides this event for handling file change events. However, this alone will not let you know what part of the file has changed.
You will need to store somewhere a copy of the file that is compared to the file whenever it changes, and then update that copy when the comparison is done. This is a very basic solution and can get really inefficient if the file is too large.
Using the FileSystemWatcher you can subscribe to the changed event ChangedEvent
FileSystemEventArgs contains a property FullPath which can be passed in to FileInfo. This will give you some basic file information, which can be stored to a database for example. You can keep a history of the file changes this way.
If you need to compare the content of the files it is more challenging and the approach will be different depending on file type.

How to programmatically determine which process created a file in .net?

There are several threads on SO that describe how to check which application creates a file with tools like Sysinternals process monitor. Is something like this possible programmatically from .net?
Background: My program has to remote-control a proprietary third party application using its automation interface, and one of the functions I need from this application has a bug where it creates a bunch of temporary files in %TEMP% that are called tmpXXXX.tmp (the same as .net's Path.GetTempFileName() does) but does not delete them. This causes the C drive to become full over time, eventually failing the application. I already filed a bug to the manufacturer, but we need a temporary workaround for the time being, so I thought of putting a FileSystemWatcher on %TEMP% that watches tmp*.tmp, collects these files, and after the operation on the third-party application finishes, deletes them. But this is risky as another application might also write files with the same file name pattern to %TEMP% so I only want to delete those created by NastyBuggyThirdPartyApplication.exe.
Is this anyhow possible?
This kind of things is possible, but maybe a bit tricky.
To know who created the file, look at the user that owns it. Therefore you might need to create a specific user, and that application will run under this specific user. In order to do that, you need to create a small application that will start your buggy app by impersonating another user, so anything done within the app will be under this user so as file creating...
I don't know how to monitor and get triggered when a file is created, but nothing can prevent you from setting a timer that wakes up every five or ten minutes, then checks if any file in the directory is owned by the application user and closed, so it deletes it.
Maybe if they react fast for this bug fixing, you won't need your app very long time. So another solution, if possible might just to change the Temp folder into another drive, which has lots of space...
One solution is that you use a FileWatcher to automatically delete all the files but before deleting you should check if the file is not currently locked or used by other process, for example the Sysinternal Suite has a tool called handle.exe that can do this. Use it from the command line:
handle.exe -a
You can invoke this from a c# program (there might be some performance issues though)
So what you would do is when a file is created you verify if it is in use or locked (for example u can use the code provided in Is there a way to check if a file is in use?) and then delete it.
Most of the time when an app is using a temp file it will lock it to prevent just what you fear, that you might delete files from other processes.
As far as I can tell there is no sure way to identify which process created a specific file.

Send File Programmability in C#

How would you go about detecting, blocking, or just in general referring to the Send File operation you can do to any file/folder on Windows. What exactly is happening when a send file happens and is there any kind of built in programmability in .NET or is it something similar to how doing a move works(It gets deleted first and then created in the new location.)
I just want to know if there is any way to detect when a Send File happens or what windows does with the file/folder when a send file is executed.
If you are speaking of the "Send To" context menu when you right-click on a file/folder, that is the result of a shell extension handler. Pretty sure there's now way to intercept those:
Is there a Click Handler for Shell Extension
MS documentation on registering/creating your own handers is below:
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144110%28v=vs.85%29.aspx
I presume that if you select "Send To" and pick a folder/drive, then it would do a standard move or copy (depending on if it is the same drive or not). As mentioned by Alan, you can use a FileSystemWatcher to try and monitor specific files/directories, but be careful being over broad with what you are watching, because there are limitations on how fast FSW can receive events, meaning if you watch to much you will miss events. Another option if you absolutely must see the file move would be to hook into the Change Journal, but that gets really ugly.
If you want to stop someone from moving or copying a file, you would have to alter its permissions for read and/or modify to exclude the user.
There is a FileSystemWatcher class that may help you detect changes to the file system. Also, the File Class has a static method for Move and other file operations. You may look into the System.IO namespace
When you move a file, it doesn't usually get recreated and deleted (if they are on the same device). Usually its location is just modified. (hence it happens almost instantly even on large files)

C#: Monitoring copied or moved files with FileSystemWatcher

I have come across several "solutions" here and across the web but none seem to fit the bill.
What I am looking to do is have an app monitor a folder for new files (either by creation, a move, or a copy) and perform actions on those objects. That being the scenario, I turned to the FileSystemWatcher class to perform this action.
The problem is that the file FileSystemWatcher.Created event is fired before the entire file is created (most noticeably seen through a copy of a large file).
Is there any way to have this event fire at the conclusion of the file creation as opposed to the beginning? I have tried various combination's of the FileSystemWatcher.NofityFilter property with no success.
Thanks in advance! :)
I have used a couple of solutions for this situation.
If you can work with the creator of the file and use a renaming scheme for the file. EG. Create the File as __Name_ while being created and at the end of the process rename it to Name and the event will fire and you have a complete file.
When your trigger fires check if you can get an exclusive readonly lock on the file. If you can then the write operation has been completed to the file. (I wrote something about this in another question Keep settings in sync between forms application and windows service (or any n-tier, really))
You could possibly integrate something like #2 into your Changed Event and then you'll get the result.
Hmm interesting problem. I never used the object while watching for big files. Did a little searching and seems one solution is to monitor the Changed event as well. Because once the file is done copying (after created is fired) a changed event is thrown as well (cause the file increased in size)
More details from what I read here: http://social.msdn.microsoft.com/forums/en-US/vblanguage/thread/f84bb7c8-b7d5-44da-b0f3-6d1a70415d11/
I know, that what I am going to tell you does not look elegant. I had also to monitor files that arrive from different places, some of them were large and some small. We found out, that FileSystemWatcher is not reliable for this purpose. If you want to be 100% sure, you can check once in a while, using Timer class and its Elapsed event.
You would need to track closing of the file after it's creation and I doubt it's possible with FileSystemWatcher.
If you don't find a solution with FileSystemWatcher, take a look at our CallbackFilter product, which lets you track all operations in real-time.

Is there any way to prevent a file from being moved in .NET?

I am loading assemblies dynamically and need to prevent being loaded files from being moved via file move or file cut and paste.
Windows does prevent the loaded assemblies from being deleted. However, I can still move the files to different directories in the same volume.
Do you know of any way to prevent a file from being moved?
Thanks.
You can set permissions to the folders you don't want users to move.
you will need to use the System.Security.AccessControl to get the file or folder access control . this post on msdn can help you use it
This may not be the easiest or the correct way to do it, but the first thing that comes to mind is a windows service project I did in college.
It was basically a service that ran, which scanned a directory, and anytime a file was changed it would notify you. This might be some way of catching the event in that directory, and if its one of the assemblies you know you don't want moved just notify the user and don't let it be moved?
Maybe this link will help, although i don't know which event would be thrown by a file being moved, i guess "Changed"?
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6165137.html
Hope this helps!
Your comment on zaladane's answer actually goes to the heart of the matter:
It [setting access rights] does not prevent the file from being moved by users with equal or higher permission.
If someone, or some process, with higher access rights than you comes along then I don't think there's anything you can do to prevent them being moved. If users need rights to the folder to install new assemblies then they'll have rights to move files.

Categories