Files can have a change date. This date is not the same as the last modified date or the last access date. Change date is not visible through the UI or .NET API. There a two Win32 functions GetFileInformationByHandleEx for reading and SetFileInformationByHandle for writing file information.
I want to read out the change date, add some hours to it, and write the new date back as the change date of the file.
For now I have following code:
class Program
{
static void Main(string[] args)
{
using (var file = new FileStream(@"c:\path\to\file", FileMode.Open))
{
var fileInfo = new FILE_BASIC_INFO();
GetFileInformationByHandleEx(
file.Handle,
FILE_INFO_BY_HANDLE_CLASS.FileBasicInfo,
out fileInfo,
(uint)Marshal.SizeOf(fileInfo));
SetFileInformationByHandle(
file.Handle,
FILE_INFO_BY_HANDLE_CLASS.FileBasicInfo,
fileInfo,
(uint)Marshal.SizeOf(fileInfo));
}
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetFileInformationByHandleEx(
IntPtr hFile,
FILE_INFO_BY_HANDLE_CLASS infoClass,
out FILE_BASIC_INFO fileInfo,
uint dwBufferSize);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetFileInformationByHandle(
IntPtr hFile,
FILE_INFO_BY_HANDLE_CLASS infoClass,
FILE_BASIC_INFO fileInfo,
uint dwBufferSize);
private enum FILE_INFO_BY_HANDLE_CLASS
{
FileBasicInfo = 0
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct FILE_BASIC_INFO
{
public LARGE_INTEGER CreationTime;
public LARGE_INTEGER LastAccessTime;
public LARGE_INTEGER LastWriteTime;
public LARGE_INTEGER ChangeTime;
public uint FileAttributes;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
private struct LARGE_INTEGER
{
[FieldOffset(0)]
public Int64 QuadPart;
[FieldOffset(0)]
public UInt32 LowPart;
[FieldOffset(4)]
public Int32 HighPart;
}
}
I can read out the change date into that awful structure LARGE_INTEGER
. What I want to have is a function which can convert that type into a System.DateTime
and vice versa.
The second problem that I have is that the siganture of the SetFileInformationByHandle method is wrong. I get a PInvokeStackImbalance with this additional information:
Additional information: A call to PInvoke function 'Program::SetFileInformationByHandle' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Who can help me?