[Universal Windows App] - How to Get the Last Write Time of a File From StorageFile
The build-in StorageFile class does not provide any property to get the last write time of a file explicitly, but you can get it through GetBasicPropertiesAsync method. This blog just describe how to use the underlying Windows API to achieve it.
In this scenario, we need to use the underlying Windows API: CreateFile2 and GetFileTime.
In C++:
create_task(Windows::ApplicationModel::Package::Current->InstalledLocation->GetFileAsync("Assets\\StoreLogo.png")).then([this](StorageFile^ file) {
HANDLE hFile = CreateFile2(file->Path->Data(), // lpFileName
GENERIC_READ, // dwDesiredAccess
FILE_SHARE_READ, // dwShareMode
OPEN_EXISTING, //
NULL);
FILETIME lastModify;
SYSTEMTIME systemTime;
GetFileTime(hFile, NULL, NULL, &lastModify);
FileTimeToSystemTime(&lastModify, &systemTime);
CloseHandle(hFile);
});
In C#:
const uint GENERIC_READ = 0x80000000;
const uint FILE_SHARE_READ = 0x00000001;
const uint OPEN_EXISTING = 3;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern SafeFileHandle CreateFile2(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
uint dwCreationDisposition,
IntPtr pCreateExParams);
[DllImport("kernel32.dll")]
static extern bool GetFileTime(
IntPtr hFile,
ref FILETIME lpCreationTime,
ref FILETIME lpLastAccessTime,
ref FILETIME lpLastWriteTime);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
[StructLayout(LayoutKind.Sequential)]
private struct FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Assets\StoreLogo.png");
FILETIME fCreationTime = new FILETIME();
FILETIME fLastAccessTime = new FILETIME();
FILETIME fLastWriteTime = new FILETIME();
var hFile = CreateFile2(file.Path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, IntPtr.Zero);
GetFileTime(hFile.DangerousGetHandle(), ref fCreationTime, ref fLastAccessTime, ref fLastWriteTime);
var lastWriteTime = DateTime.FromFileTimeUtc((((long)fLastWriteTime.dwHighDateTime) << 32) | ((uint)fLastWriteTime.dwLowDateTime));
hFile.DangerousRelease();
}