pythonpywin32pywin

Changing directory create times (ctime) using python in windows


I am trying to change the directory creation timestamp for a windows system using python. I have a directory that was copied over from another drive and the directory creation times are not preserved. This is what I am hoping to do,

Step 1 : Read the source directory list and thier creation times with the following code,

import os
source_dir_path = r'd:\data'
list_of_directories = os.listdir(source_dir_path)
creation_times = {}
for d in list_of_directories:
    creation_times[d] = os.path.getctime(os.path.join(source_dir_path, d))

Step 2 : Iterate over the directory list and set the Directory Creation Time. For this I am relyting on Python For Windows Extensions. Code is shown below,

from win32file import CreateFile, SetFileTime, GetFileTime, CloseHandle
from win32file import GENERIC_READ, GENERIC_WRITE, OPEN_EXISTING
from pywintypes import Time

destination_dir_path = r'f:\data'
#list_of_directories = os.listdir(source_dir_path)
for d in creation_times:
    fh = CreateFile(os.path.join(destination_dir_path,d), 0, 0, None, OPEN_EXISTING, 0,0)
    SetFileTime(fh, creation_times[d]) 

I am getting an 'Access is Denied' at the CreateFile line. I am not sure if this a valid way to setting creation time for the directory. Is this the right way set directory creation times


Solution

  • The following approach should work, although this does set the creation time also for the last access and last write times also. It creates a list of tuples (rather than a dictionary) of the filenames and creation times, copies the files from the source to the target directory. The main issue your code had was the parameters needed for the CreateFile call:

    from win32file import CreateFile, SetFileTime, GetFileTime, CloseHandle
    from win32file import GENERIC_WRITE, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, FILE_SHARE_WRITE
    
    import os
    import shutil
    
    source_dir_path = r"c:\my_source"
    destination_dir_path = r"c:\my_target"
    
    creation_times = [(d, os.path.getctime(os.path.join(source_dir_path, d))) for d in os.listdir(source_dir_path)]
    
    for filename, ctime in creation_times:
        src = os.path.join(source_dir_path, filename)
        target = os.path.join(destination_dir_path, filename)
        shutil.copy(src, target)
    
        fh = CreateFile(target, GENERIC_WRITE, FILE_SHARE_WRITE, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
        SetFileTime(fh, ctime, ctime, ctime)    
        CloseHandle(fh)