FileSystemInfo.LastWriteTime property is readonly in CF.
Is there an alternative way to change that date?
            Asked
            
        
        
            Active
            
        
            Viewed 1,174 times
        
    2
            
            
        - 
                    You could always *write to the file*. That's a good way of updating it; anything else would be a little disingenuous, wouldn't you agree? – Cody Gray - on strike Apr 15 '11 at 08:09
 - 
                    I agree...but I need to put the original date on a file downloaded from FTP. – fra Apr 15 '11 at 09:49
 
2 Answers
4
            P/Invoke SetFileTime.
EDIT
Something along these lines (warning: untested)
[DllImport("coredll.dll")]
private static extern bool SetFileTime(string path,
                                      ref long creationTime,
                                      ref long lastAccessTime,
                                      ref long lastWriteTime);
public void SetFileTimes(string path, DateTime time)
{
    var ft = time.ToFileTime();
    SetFileTime(path, ref ft, ref ft, ref ft);
}
        ctacke
        
- 66,480
 - 18
 - 94
 - 155
 
- 
                    Sorry...what's the CLR type for FILETIME? is this signature correct? [DllImport("coredll.dll")] public static extern bool SetFileTime(IntPtr path, ref long? creationTime, ref long? lastAccessTime, ref long? lastWriteTime); – fra Apr 15 '11 at 13:41
 - 
                    Yeah this doesn't work for me, the file creation time is still at UTC time even though the date I pass in is the correct local time, seems the CE edition is changing any file created to UTC. – JPM Aug 22 '11 at 17:20
 - 
                    @JPM: It's setting the file time properly, it's just not matching your expectation that it should be a local time. The docs don't actually say if the times should be system or local. If you call `ToUniversalTime()` on the value before you send it in and you'll get the behavior you're expecting. – ctacke Aug 22 '11 at 18:28
 
1
            
            
        Here is a fuller implementation, adapted from the answer ctacke provides above and this StackOverflow question. I hope this proves useful to someone:
// Some Windows constants
// File access (using CreateFileW)
public const uint GENERIC_READ          = 0x80000000;
public const uint GENERIC_WRITE         = 0x40000000;
public const uint GENERIC_READ_WRITE    = (GENERIC_READ + GENERIC_WRITE);
public const int INVALID_HANDLE_VALUE   = -1;
// File creation (using CreateFileW)
public const int CREATE_NEW             = 1;
public const int OPEN_EXISTING          = 3;
// File attributes (using CreateFileW)
public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
// P/Invokes
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr CreateFileW(
    string lpFileName,
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr pSecurityAttributes,
    uint dwCreationDisposition,
    uint dwFlagsAndAttributes,
    IntPtr hTemplatefile);
[DllImport("coredll.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr hObject);
// Note: Create related P/Invokes to change creation or last access time.
// This one modifies the last write time only.
[DllImport("coredll.dll", EntryPoint = "SetFileTime", SetLastError = true)]
private static extern bool SetFileWriteTime(
    IntPtr hFile,
    IntPtr lpCreationTimeUnused,
    IntPtr lpLastAccessTimeUnused,
    ref long lpLastWriteTime);
// Open a handle to the file you want changed
IntPtr hFile = CreateFileW(
    path, GENERIC_READ_WRITE, 0,
    IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
    IntPtr.Zero);
// Modify the last write time and close the file
long lTimeNow = DateTime.Now.ToFileTime();
SetFileWriteTime(hFile, IntPtr.Zero, IntPtr.Zero, ref lTimeNow);
CloseHandle(hFile);
Note that you can use System.IO.File.GetLastWriteTime (which is exposed in the .NET Compact Framework) to read the last write time if required.