While the documentation is vague, based on this question and comments and this answer, I expected that ReplaceFile
called with the third argument (backup filename) should succeed even if there are handles to source and destination files open in other processes without FILE_SHARE_DELETE
flag. It's supposed to be overcome the lock by changing just the file metadata (= directory entry), which is not controlled by the lock. (All three files are on the same disk drive, so changing metadata is enough to rename them.)
However, the code below fails with ERROR_SHARING_VIOLATION
. This is not my use case, but just a demonstration of the failure. The use case is that I'm trying to rename files that are occasionally (and unpredictably) open in other processes on the system, such as antivirus or backup programs, which didn't bother to use FILE_SHARE_DELETE
flag.
# python 3
import os
import ctypes
fname1 = 'test1.txt'
fname2 = 'test2.txt'
f1 = open(fname1, 'w')
f1.write(fname1)
f2 = open(fname2, 'w')
f2.write(fname2)
# tmp123 does not exist when the program is started
ctypes.windll.kernel32.ReplaceFileW(fname2, fname1, 'tmp123', 0, None, None) # 0
ctypes.GetLastError() # ERROR_SHARING_VIOLATION
# if we close file handles, it works as expected
f1.close()
f2.close()
ctypes.windll.kernel32.ReplaceFileW(fname2, fname1, 'tmp123', 0, None, None) # 1
Why?