How do I get *change* file time in Windows?

∥☆過路亽.° 提交于 2019-12-06 03:40:18

问题


I am trying to use FreeNAS CIFS share with Windows (synchronizing files from Windows to FreeNAS) and hit a problem that robocopy.exe thinks that some files need to be copied again every time I run robocopy.exe (/COPY:DAT).

My favorite file management tool, Far Manager, tells me that "Change time" is different:

File times on Windows:

File times on CIFS share backed by FreeNAS (ZFS):

I am perfectly fine with the fact that "change time" is lost, and I'd be happy to reset change time on the Windows drive, but I can't find how I can do that programmatically.

Python's os.stat(filename) returns st_atime, st_mtime and st_ctime, and, I've tested, this tuple has equal values between Windows and FreeNAS. Presumably "change time" isn't there.

Windows API also gives only 3 numbers (creation, last access and last write) but not "change time": http://msdn.microsoft.com/en-us/library/windows/desktop/ms724320(v=vs.85).aspx

Apparently both robocopy.exe and Far Manager somehow get 4 values from the system. I'd really like to avoid disassembling them, hoping to get an answer here. How do I get and set "change time"?

Any solution will do (Python, C++, WinAPI, external command line tools that can manipulate that, etc).


回答1:


OK, I seem to have figured it out, thanks to cocarin for pointing to Far sources. Far uses NtQueryInformationFile to get times and NtSetInformationFile to set them, and FILE_BASIC_INFORMATION structure contains all 4 times, including change time.

QueryInformationFile docs: http://msdn.microsoft.com/en-us/library/windows/hardware/ff567052(v=vs.85).aspx (ZwQueryInformationFile)

SetInformationFile docs: http://msdn.microsoft.com/en-us/library/windows/hardware/ff567096(v=vs.85).aspx (ZwSetInformationFile)

FILE_BASIC_INFORMATION docs: http://msdn.microsoft.com/en-us/library/windows/hardware/ff545762(v=vs.85).aspx

typedef struct _FILE_BASIC_INFORMATION {
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;        // <--- win!
  ULONG         FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

Not sure if there are any nice wrappers for Python but this is good enough, I can write my own wrapper.




回答2:


There is a better way than the accepted answer, without having to resort to native system Zw* calls on Windows Vista and higher (Server 2008 and higher).

Please take a look at the following sample code I whipped up to show how:

// Get a handle to the file whose change time you want
const WCHAR pathName[]=L"..."; // The name of the file
HANDLE hFile=::CreateFileW(
               pathName, 
               GENERIC_READ, 
               FILE_SHARE_READ /* | FILE_SHARE_WRITE */,
               NULL, 
               OPEN_EXISTING,  // Fail if file does not exist
               FILE_ATTRIBUTE_NORMAL, 
               NULL);

// If file exists and can be read...
if (hFile!=INVALID_HANDLE_VALUE)
{
  FILE_BASIC_INFO fileBasicInfo={};

  // Get the info we are after
  if (::GetFileInformationByHandleEx(
        hFile,
        FileBasicInfo,          // Info class from FILE_INFO_BY_HANDLE_CLASS enum
        &fileBasicInfo,         // Where to store the info
        sizeof(fileBasicInfo))  // Buffer size
  {
      // Use fileBasicInfo.ChangeTime for the file change time
      ...
  }

  ::CloseHandle(hFile);
}

Here are the corresponding MSDN entry links for your convenience:

  • GetFileInformationByHandleEx function
  • FILE_BASIC_INFO structure
  • FILE_INFO_BY_HANDLE_CLASS Enumeration

Note: Also, take a look at the other information classes that are available with this treasure trove of a function for all your advanced file info needs. For example, the FileStandardInfo class gives you such useful tidbits as the amount of space actually allocated to the file (e.g., for sparse file actual physical space use), the number of links, is a delete pending, is it a directory, etc...



来源:https://stackoverflow.com/questions/27534448/how-do-i-get-change-file-time-in-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!