2

Before you send me links to here, here and maybe here bear with me.

I'd like to write a service that monitors changes of a given set of files and I started with the simplest thing writing console application that monitors directory in order to continue with my POC. However, I got stuck trying to extract the actual changes that were made. (Yes, I managed to handle the event in the FileSystemWatcher class, but as far as I see the API of the class I am unable to track the actual changes)

Do you know if there is a way to do so? Maybe without so much pain or unnecessary operations.

I am currently using .NET Core 2.0, but any version of .NET Core will do.

EDIT: The files I need to monitor are text based, basically I want to implement git diff functionality and report the changes.

kuskmen
  • 3,648
  • 4
  • 27
  • 54
  • 2
    What sort of "changes" to the file are you talking about? Is this a binary file or plain text? Changing "teh" to "the" is different than changing 001010 to 110101 in the middle of a binary file. Well at the lowest level it's not but you should elaborate. – Patrick Nov 17 '17 at 00:10
  • 2
    Good point, I am talking only about text based files, so any changes will do, later I might want to decide to implement a way of tracking only relevant changes but this is another topic for now I want to see how the file changed (precisely like git diff does) – kuskmen Nov 17 '17 at 00:12
  • Have you looked at https://jeremylindsayni.wordpress.com/2016/04/10/how-to-use-the-filesystemwatcher-in-c-to-report-file-changes-on-disk/ – Patrick Nov 17 '17 at 00:17
  • This is really well documented on MSDN, `FileSystemWatcher` exposed a bunch of events you are meant to subscribe to? – zaitsman Nov 17 '17 at 00:22
  • 2
    @zaitsman Tell me you havent read the question please, otherwise I would be shocked. – kuskmen Nov 17 '17 at 00:34
  • 2
    While so many others get it working, I am surprised that you don't even find a working sample first, and keep saying "stuck" or "shocked". Even the test cases Microsoft makes should be quite helpful to understand the API itself, https://github.com/dotnet/corefx/tree/master/src/System.IO.FileSystem.Watcher/tests – Lex Li Nov 17 '17 at 02:44
  • @kuskmen it is hard to understand what `However, I got stuck trying to extract the actual changes that were made` means. there is no code in your question. – zaitsman Nov 17 '17 at 02:57
  • 1
    AFAIK, this is not supported by the API. Most platforms do not keep track of the actual changes in the file; they just report that the file changed and they know the new contents. For example, on Linux, this is built on top of `inotify`. That only gets you the file (name) that changed. .NET Core can not provide a platform-agnostic way to expose a functionality that doesn't exist on all platforms. To do git-like diff, you will probably have to use some sort of version control system. – omajid Nov 17 '17 at 03:26
  • @Patrick, I've seen this blogpost but it doesn't cover the use case I am looking for. – kuskmen Nov 17 '17 at 09:44
  • @omajid , I am not worried that my solution will be platform specific, I am worried if I start reinventing the wheel, but seems like people say there is no way tracking the actual changes of a file using some platform API or at least thats what it seems – kuskmen Nov 18 '17 at 09:43

1 Answers1

5

The short answer is no, there is no API that will tell you which part of the file was modified. All you can get from the OS is a notification that a change has occurred to a file, not the nature or location of that change beyond what you get from the FileSystemWatcher.

To detect the nature of the change you need to be able to compare the contents of the file before and after the change. In most cases you won't have access to the prior state of the file. You could use shadow copies to access the prior state of the file, but that has issues of its own.

If you're monitoring only a small number of files then you can do some sort of fingerprinting - block level hashing for instance - to detect the location of the change. You'll still need a before and after to detect the particular change.

That said...

It is in principle possible to hook into the Windows APIs that are used to actually write data to the disk. I haven't tried this with .NET but I've used Detours in the past to do similar things. Be aware that API hooking is dangerous territory, and if you get it wrong you can kill your computer. Here be dragons. If you want to go this route I strongly suggest that you write your code with an eye towards minimising delays.

Corey
  • 15,524
  • 2
  • 35
  • 68