Por que ReplaceFile falha com ERROR_SHARING_VIOLATION?
Embora a documentação seja vaga, com base emesta pergunta e comentários eesta resposta, Eu esperei issoReplaceFile
chamado com o terceiro argumento (nome do arquivo de backup) deve ter êxito mesmo se houver identificadores para os arquivos de origem e destino abertos em outros processos semFILE_SHARE_DELETE
bandeira. É suposto superar o bloqueio alterando apenas os metadados do arquivo (= entrada do diretório), que não são controlados pelo bloqueio. (Todos os três arquivos estão na mesma unidade de disco, portanto, alterar metadados é suficiente para renomeá-los.)
No entanto, o código abaixo falha comERROR_SHARING_VIOLATION
. Isto énão meu caso de uso, mas apenas uma demonstração da falha. O caso de uso é que estou tentando renomear arquivos que ocasionalmente (e imprevisivelmente) são abertos em outros processos no sistema, como antivírus ou programas de backup, que não se preocuparam em usarFILE_SHARE_DELETE
bandeira.
# 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
Por quê?