Я адаптировал скрипт, опубликованный Apple16 выше, для запуска в Python 3 и немного его улучшил. Используя комбинацию выборочного исключения папок из истории файлов и этого сценария для просмотра возможных проблем, я сузил свою проблему до двух файлов с почти одинаковыми именами в одном каталоге. Оба файла имели слово Espanol в имени файла с тильдой над n. Однако у одного была кодировка: Espan\N {COMBINING TILDE} ol, а у другого - Espa\N {LATIN SMALL LETTER N WITH TILDE} ol. Оба имени файла одинаково перечислены в Проводнике Windows с тильдой над n. Когда я помещаю эти два файла в отдельные папки, они прекрасно сохраняются в истории файлов, но, находясь в одном и том же каталоге, они, похоже, мешают друг другу и блокируют работу истории файлов.
Вот скрипт CheckFileNames.py, который я использовал:
#CheckFileNames.py, 10 May 2016, LewisN
#Python 3 version adapted and enhanced by LewisN; based on script by apple16 posted on http://superuser.com/
#Scans Windows file system for potentially problematic directories and files affecting File History operation.
#---------------------------------------------------------------------------------
#SET THE FOLLOWING BEFORE RUNNING:
DirectoryTreeToScan = r'C:\Users\<username>'
DaysBackToList = 0 #Number of days back to list. Set to 0 to list all FLAGGED FILES regardless of file dates.
PrintDates = False #Set True to show File Creation and Modification dates.
#You may also want to play with the following settings:
flagDirLen=200
flagFullNameLen=200
# Max filename len on Windows is ~255, but File History adds "F:\FileHistory\<username>\<computer name>\Data" to
# the front the files and a timestamp to the end, so backing off on name lengths flagged to be safe.
# Files with long filenames are actually saved to F:\FileHistory\<username>\<computer name>\Data\$OF and can be
# retrieved using the File History GUI, but you may want to avoid this. Also there may be cases where
# long paths and/or filenames cause errors.
#Notes:
# 1. Filenames with Unicode characters from various languages are also often ok for File History.
# This script exposes these characters so they can be examined for potential problems.
# 2. Filenames with initial dots (also flagged here) are ok for File History (use cmd prompt to edit them).
#---------------------------------------------------------------------------------
import os,string,time,datetime
import sys
validChars="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. #^=!()&,_'-+@%[]{$};`~"
disallowedChars=r'\/:*?"<>|'
# Note that many other characters are also actually allowed. Windows expressly disallows \/:*?"<>|
lastdirheader=''
def PrintDirHeaderIfNeeded():
global lastdirheader
if currdir!=lastdirheader:
print ('===FLAGGED FILES IN DIRECTORY',currdir.encode("ascii","replace").decode()+':')
lastdirheader = currdir
return;
def PrintFileDates():
fname=os.path.join(currdir,filename)
print(' Created: ' + time.ctime(os.path.getctime(fname)) + ', Modified: ' + time.ctime(os.path.getmtime(fname)))
return;
def IsRecent(DaysBack):
fname=os.path.join(currdir,filename)
if DaysBack==0: return True # 0 disables limiting file listings based on file dates
if ((datetime.datetime.now()-datetime.datetime.fromtimestamp(os.path.getctime(fname))).days<DaysBack) or \
((datetime.datetime.now()-datetime.datetime.fromtimestamp(os.path.getmtime(fname))).days<DaysBack):
return True
else: return False;
for currdir,folders,filenames in os.walk(DirectoryTreeToScan):
if len(currdir)>flagDirLen:
print('===DIRLEN>' + str(flagDirLen) + ':', currdir.encode("ascii","replace").decode())
if ''.join([x for x in currdir[2:].replace('\\','') if x in validChars])!=currdir[2:].replace('\\',''):
print('===DIR CHARS+:',currdir.encode("ascii","namereplace").decode())
for filename in filenames:
if (len(currdir)+len(filename)>flagFullNameLen) and IsRecent(DaysBackToList):
PrintDirHeaderIfNeeded()
print(' FULLNAMELEN>' + str(flagFullNameLen) + ':', filename.encode("ascii","replace").decode())
if PrintDates: PrintFileDates()
if ''.join([x for x in filename if x in validChars])!=filename and IsRecent(DaysBackToList):
PrintDirHeaderIfNeeded()
print(' CHARS+:',filename.encode("ascii","namereplace").decode())
if PrintDates: PrintFileDates()
if filename[0:1] == "." and IsRecent(DaysBackToList):
PrintDirHeaderIfNeeded()
print(' INITIAL DOT:',filename.encode("ascii","replace").decode())
if PrintDates: PrintFileDates()
if any(True for x in filename if x in disallowedChars) and IsRecent(DaysBackToList):
PrintDirHeaderIfNeeded()
print(' DISALLOWED (' + disallowedChars + '):',filename.encode("ascii","replace").decode())
if PrintDates: PrintFileDates()