Send File Programmability in C# - 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)

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 intercept Win32 API calls with C#?

I would like to either host a virtual drive and intercept the I/O, or intercept I/O calls to certain folders on a hard drive, and do arbitrary things to that call like write the file to a 2nd location. For example, if Notepad.exe writes a file to C:\Data\test.txt - I would like to have access to that file name, and the data of the file. Likewise, I would like to run arbitrary code when any user attempts to read C:\Data\test.txt or attempts to get a directory listing for C:\Data.
Ideally I want to have a handler for when a file is: created, updated, deleted, or opened - and when someone does a directory listing (from command-line or from the Shell).
I can do the write part with FileSystemWatcher - but I can't intercept disk "reads". So, I next looked into MS Detours and EasyHook. That won't really work because I'd need to monitor every single process on the computer and hook to OpenFile on ALL of them. I don't want to use a Shell Extension because this behavior needs to exist from the command-line too. So, that leaves either writing a File System MiniFilter driver - or writing my own installable file system in C++.
I can have some portion of this in C++ - although the driver stuff is a bit over my head, but ultimately most of the rest of code should be in C#, ideally.
Is there some straightforward way to intercept I/O to a specific folder or virtual drive? If the answer is with EasyHook or a MiniFilter, does anyone have any samples? EasyHook in particular only has samples from the late-2000s and the API has changed since then. Thanks!
Looks like an XY problem. What you seem to want are reparse point handlers.
Your example of "writing a file to another location" is just a link, and those already exist. Implemented by a standard reparse point handler.
You don't specify exactly what else you want to do, but similar things can be done by custom reparse point handlers. In short, a reparse point is a small bit of data in place of a file, which (1) specifies which handler should be called, and (2) provides custom data to that handler. For instance, the actual location of the file. Since it's custom data, you can use any format you like.

Detect and Log copy/paste/delete/cut operations in File Explorer

I want to detect and log to file Explorer operations such as copy/cut/delete/paste.
I have read about FileSystemWatcher, but I also noticed it has some issues since there is no copy/cut events available which can be confusing with whatever I want to do.
The operating system and FileSystemWatcher object interpret a cut-and-paste action or a move action as a rename action for a folder and its contents. If you cut and paste a folder with files into a folder being watched, the FileSystemWatcher object reports only the folder as new, but not its contents because they are essentially only renamed.
FileSystemWatcher is hooking the create file and delete file events to the changed and renamed events which can't really help me to determine if it was made by the user or some another process. Furthermore I cannot be 100% sure what happened to the file whether it was copied or cut etc.
I also need to keep track of the locations "from/to" and the name of file.
Is there some alternative to the FileSystemWatcher that can distinguish between these actions?
I think the FileSystemWatcher would be of use in this scenario. You could use the Changed event, which occurs when a file or directory is changed - like a copy/paste action.
See the MSDN Documentation for this event, and the class itself. Note that there are other events that you can also use for the delete/cut actions.
The events use the FileSystemEventArgs which contains properties for FullPath and Name.

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.

Hooking my program with windows explorer's rename event

Is there any way, in any language, to hook my program when a user renames a file?
For example:
A user renames a file and presses enter (or clicks away) to confirm the rename action. BEFORE the file is actually renamed, my program "listens" to this event and pops up a message saying "Are you sure you want to rename C:\test\file.txt to C:\test\test.txt?".
I'm thinking/hoping this is possible with C++, C# or .NET.. But I don't have any clue where to look for.
You can probably solve this by using the FileSystemWatcher class in .NET framework.
From the class remarks:
You can watch for renaming, deletion,
or creation of files or directories.
For example, to watch for renaming of
text files, set the Filter property to
"*.txt" and call the WaitForChanged
method with a Renamed specified for
its parameter.
My guess is that this is not possible, I did find this which is for monitoring operations (including rename) on a folder, but there does not appear to be a similar method for files.
#Richard, FileSystemWatcher is good if you only need to monitor changes, but he needs to interrupt them which it cannot do.
IFileOperationProgressSink.PreRenameItem is the closest supported thing I know of. Unfortunately, it's not a hook into Explorer - so you can only use it for your own IFileOperation actions. Depending on your needs, you can write a shell extension to do your own ConfirmRename (or something), and branch from there.
Otherwise, you're looking at hooking SHFileOperation, I think. This would have to be done in unmanaged code, as you'll be loaded into Explorer.exe. For Vista, this has been changed to IFileOperation - which probably means you'll have to hook the creation of it and pass out your mock.
Personally, I think since you're talking a rename, wilhelmtell's idea of confirming after the change, and undoing it if necessary is the best idea.

Categories