tanascius
tanascius

Reputation: 53964

How to change a file without affecting the "last write time"

I would like to write some stuff to file, like

using( var fs = File.OpenWrite( file ) )
{
  fs.Write( bytes, 0, bytes.Length );
}

However, this changes the "last write time". I can reset it later, by using

File.SetLastWriteTime( file, <old last write time> );

But in the meantime, a FileSystemWatcher already triggers.

Now my question: Is is possible to write a file without altering the "last write time"?

Upvotes: 4

Views: 1662

Answers (3)

KUNGERMIOoN
KUNGERMIOoN

Reputation: 21

Answer by John Willemse didn't work for me - it turns out fileTimeUnchanged had to be set to 0xFFFFFFFFFFFFFFFF rather than 0xFFFFFFFF. This is because (according to the docs) you need to pass the FILETIME structure with both DWORDs set to 0xFFFFFFFF. Passing 0xFFFFFFFF as the entire structure would give dwLowDateTime the correct value, but dwHighDateTime would be 0.

Upvotes: 2

John Willemse
John Willemse

Reputation: 6698

You can achieve it by using P/Invoke calls in Kernel32.dll.

This Powershell script from MS TechNet achieves it, and explicitly states that a FileSystemWatcher's events are not triggered.

I have briefly looked into the script and the code is pretty straightforward and can easily be copied to your C# project.

Declaration:

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetFileTime(IntPtr hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);

The script uses SetFileTime to lock the file times before writing.

private const int64 fileTimeUnchanged = 0xFFFFFFFF;

This constant is passed as reference to the method for lpCreationTime, lpLastAccessTime and lpLastWriteTime:

// assuming fileStreamHandle is an IntPtr with the handle of the opened filestream
SetFileTime(fileStreamHandle, ref fileTimeUnchanged, ref fileTimeUnchanged, ref fileTimeUnchanged);
// Write to the file and close the stream

Upvotes: 4

Tigran
Tigran

Reputation: 62265

Don't think it's possible,nor that I'm aware of.

Also consider that "last write time" Is Not Always Updated, which leads to some wired results if you're going to pick (say) some files from the folder based on that parameter or rely on that property in some way. So it's not a parameter you can rely on in your development, it's just not reliable by architecture of OS.

Simply create a flag: boolean, if this you write and watch into the same application, or a flag, like some specific named file, if you write form one and watch from another application.

Upvotes: 2

Related Questions