last version published here https://github.com/dreamer2/steambulkvalidate
When manually closing the validate window, the process will stop and cannot resume automatically.
1. Install python.
2. Install python modules :
pip install vdf
pip install pywin32
3. Create two files and run in admin console python.exe validate.py
steamfolders.json
[
"c:\\Program Files (x86)\\Steam\\steamapps\\",
"d:\\SteamLibrary\\steamapps\\"
]
---------------------------
validate2.py - updated version, testing needed
import os
import re
import time
import vdf
import json
import winreg
import win32api
import datetime
from datetime import datetime as dt
def formatTime(elapsed_time):
if elapsed_time < 3600:
minutes, seconds = divmod(elapsed_time, 60)
return "{:.0f}m ".format(minutes)
elif elapsed_time < 86400:
hours, remainder = divmod(elapsed_time, 3600)
minutes, seconds = divmod(remainder, 60)
return "{:.0f}h {:.0f}m".format(hours, minutes)
else:
days, remainder = divmod(elapsed_time, 86400)
hours, remainder = divmod(remainder, 3600)
minutes, seconds = divmod(remainder, 60)
return "{:.0f}d {:.0f}h {:.0f}m".format(days, hours, minutes)
def waitForLogFile(appID, filePosition):
currentLogSize = os.path.getsize(logFilename)
while True:
if os.path.getsize(logFilename) > currentLogSize:
with open(logFilename, 'r') as log_file:
log_file.seek(filePosition)
for line in log_file:
logMatch = re.search(
r'.+AppID '+str(appID)+' scheduler finished : removed from schedule \(result (.+),.+\)', line)
if logMatch:
result = logMatch.group(1)
return result
currentLogSize = os.path.getsize(logFilename)
filePosition = currentLogSize
time.sleep(0.5)
def ProcessSteamFolder(directory):
global current
for filename in os.listdir(directory):
if filename.endswith('.acf'):
filepath = os.path.join(directory, filename)
with open(filepath, 'r') as f:
acf_data = vdf.load(f)
app_id = acf_data['AppState']['appid']
name = acf_data['AppState']['name']
installdir = '"' + \
os.path.join(directory, 'common',
acf_data['AppState']['installdir'])+'"'
ctime = dt.now()
ftime= f'{ctime.hour:02}:{ctime.minute:02}'
if app_id in finishedData:
print(
f'{current:02}/{total:02} {ftime} Пропуск {name} : {app_id} : {installdir}, уже в списке завершенного.')
else:
print(
f'{current:02}/{total:02} {ftime} Запуск проверки {name} : {app_id} : {installdir}, ожидаю завершения.')
cmd = f'/c start steam://validate/{app_id}'
filePosition = os.path.getsize(logFilename)
win32api.ShellExecute(0, "open", 'cmd.exe', cmd, "", 1)
result = waitForLogFile(app_id, filePosition)
ctime = dt.now()
ftime= f'{ctime.hour:02}:{ctime.minute:02}'
print(
f'{current:02}/{total:02} {ftime} проверка завершена {name} : {app_id} : {installdir}, {result}.')
finishedData[app_id] = name
if storeFinished:
try:
with open(finishedPath, 'w') as f:
json.dump(finishedData, f, indent=4)
except:
pass
time.sleep(4)
current += 1
storeFinished = True
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
"SOFTWARE\\WOW6432Node\\Valve\\Steam")
steamFolder = winreg.QueryValueEx(key, "InstallPath")[0]
logFilename = os.path.join(steamFolder, "logs", "content_log.txt")
currentDate = datetime.date.today().strftime("%Y-%m-%d")
finishedPath = f"finished-{currentDate}.json"
finishedData = {}
if storeFinished:
try:
with open(finishedPath, 'r') as f:
finishedData = json.load(f)
except:
pass
alreadyProcessed = len(finishedData)
folderErrors = 0
total = 0
current = 1
startTime = time.time()
with open("steamfolders.json", 'r') as f:
steamFolders = json.load(f)
for folder in steamFolders:
if os.path.isdir(folder):
for filename in os.listdir(folder):
if filename.endswith('.acf'):
total += 1
with open("steamfolders.json", 'r') as f:
steamFolders = json.load(f)
for folder in steamFolders:
if os.path.isdir(folder):
ProcessSteamFolder(folder)
else:
folderErrors += 1
endTime = time.time()
elapsedTime = endTime - startTime
print(f'Работа завершена, время '+formatTime(elapsedTime) +
f', всего игр {len(finishedData)}, пропущено {alreadyProcessed}, ошибок пути {folderErrors}.')
import re
import time
import vdf
import json
import winreg
import win32api
import datetime
from datetime import datetime as dt
def formatTime(elapsed_time):
if elapsed_time < 3600:
minutes, seconds = divmod(elapsed_time, 60)
return "{:.0f}m ".format(minutes)
elif elapsed_time < 86400:
hours, remainder = divmod(elapsed_time, 3600)
minutes, seconds = divmod(remainder, 60)
return "{:.0f}h {:.0f}m".format(hours, minutes)
else:
days, remainder = divmod(elapsed_time, 86400)
hours, remainder = divmod(remainder, 3600)
minutes, seconds = divmod(remainder, 60)
return "{:.0f}d {:.0f}h {:.0f}m".format(days, hours, minutes)
def waitForLogFile(appID, filePosition):
currentLogSize = os.path.getsize(logFilename)
while True:
if os.path.getsize(logFilename) > currentLogSize:
with open(logFilename, 'r') as log_file:
log_file.seek(filePosition)
for line in log_file:
logMatch = re.search(
r'.+AppID '+str(appID)+' scheduler finished : removed from schedule \(result (.+),.+\)', line)
if logMatch:
result = logMatch.group(1)
return result
currentLogSize = os.path.getsize(logFilename)
filePosition = currentLogSize
time.sleep(0.5)
def ProcessSteamFolder(directory):
global current
for filename in os.listdir(directory):
if filename.endswith('.acf'):
filepath = os.path.join(directory, filename)
with open(filepath, 'r') as f:
acf_data = vdf.load(f)
app_id = acf_data['AppState']['appid']
name = acf_data['AppState']['name']
installdir = '"' + \
os.path.join(directory, 'common',
acf_data['AppState']['installdir'])+'"'
ctime = dt.now()
ftime= f'{ctime.hour:02}:{ctime.minute:02}'
if app_id in finishedData:
print(
f'{current:02}/{total:02} {ftime} Пропуск {name} : {app_id} : {installdir}, уже в списке завершенного.')
else:
print(
f'{current:02}/{total:02} {ftime} Запуск проверки {name} : {app_id} : {installdir}, ожидаю завершения.')
cmd = f'/c start steam://validate/{app_id}'
filePosition = os.path.getsize(logFilename)
win32api.ShellExecute(0, "open", 'cmd.exe', cmd, "", 1)
result = waitForLogFile(app_id, filePosition)
ctime = dt.now()
ftime= f'{ctime.hour:02}:{ctime.minute:02}'
print(
f'{current:02}/{total:02} {ftime} проверка завершена {name} : {app_id} : {installdir}, {result}.')
finishedData[app_id] = name
if storeFinished:
try:
with open(finishedPath, 'w') as f:
json.dump(finishedData, f, indent=4)
except:
pass
time.sleep(4)
current += 1
storeFinished = True
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
"SOFTWARE\\WOW6432Node\\Valve\\Steam")
steamFolder = winreg.QueryValueEx(key, "InstallPath")[0]
logFilename = os.path.join(steamFolder, "logs", "content_log.txt")
currentDate = datetime.date.today().strftime("%Y-%m-%d")
finishedPath = f"finished-{currentDate}.json"
finishedData = {}
if storeFinished:
try:
with open(finishedPath, 'r') as f:
finishedData = json.load(f)
except:
pass
alreadyProcessed = len(finishedData)
folderErrors = 0
total = 0
current = 1
startTime = time.time()
with open("steamfolders.json", 'r') as f:
steamFolders = json.load(f)
for folder in steamFolders:
if os.path.isdir(folder):
for filename in os.listdir(folder):
if filename.endswith('.acf'):
total += 1
with open("steamfolders.json", 'r') as f:
steamFolders = json.load(f)
for folder in steamFolders:
if os.path.isdir(folder):
ProcessSteamFolder(folder)
else:
folderErrors += 1
endTime = time.time()
elapsedTime = endTime - startTime
print(f'Работа завершена, время '+formatTime(elapsedTime) +
f', всего игр {len(finishedData)}, пропущено {alreadyProcessed}, ошибок пути {folderErrors}.')
---------------------------
validate.py - Old version
Not work starting 2023jun15 steam client update :(
import os
import time
import vdf
import json
import winreg
import win32api
import win32gui
import win32con
import datetime
def formatTime(elapsed_time):
if elapsed_time < 3600:
minutes, seconds = divmod(elapsed_time, 60)
return "{:.0f}m ".format(minutes)
elif elapsed_time < 86400:
hours, remainder = divmod(elapsed_time, 3600)
minutes, seconds = divmod(remainder, 60)
return "{:.0f}h {:.0f}m".format(hours, minutes)
else:
days, remainder = divmod(elapsed_time, 86400)
hours, remainder = divmod(remainder, 3600)
minutes, seconds = divmod(remainder, 60)
return "{:.0f}d {:.0f}h {:.0f}m".format(days, hours, minutes)
def ProcessSteamFolder(directory):
global current
for filename in os.listdir(directory):
if filename.endswith('.acf'):
filepath = os.path.join(directory, filename)
with open(filepath, 'r') as f:
acf_data = vdf.load(f)
app_id = acf_data['AppState']['appid']
name = acf_data['AppState']['name']
installdir = '"' + \
os.path.join(directory, 'common',
acf_data['AppState']['installdir'])+'"'
if app_id in finishedData:
print(f'{current}/{total} Пропуск {name} : {app_id} : {installdir}, уже в списке завершенного.')
else:
print(
f'{current}/{total} Запуск проверки {name} : {app_id} : {installdir}, ожидаю окно завершения.')
cmd = f'/c start steam://validate/{app_id}'
#print(f'cmd.exe' + cmd)
win32api.ShellExecute(0, "open", 'cmd.exe', cmd, "", 1)
finished = False
while not finished:
time.sleep(10)
hwnd1 = win32gui.FindWindow(
None, 'Проверка файлов Steam — 100% завершено')
hwnd2 = win32gui.FindWindow(
None, 'Validating Steam files - 100% complete')
#print("ru win: "+str(hwnd1)+" en win: "+str(hwnd2))
if hwnd1:
win32gui.PostMessage(hwnd1, win32con.WM_CLOSE, 0, 0)
finished = True
elif hwnd2:
win32gui.PostMessage(hwnd2, win32con.WM_CLOSE, 0, 0)
finished = True
finishedData[app_id]=name
if storeFinished:
try:
with open(finishedPath, 'w') as f:
json.dump(finishedData, f, indent=4)
except:
pass
time.sleep(4)
current+=1
storeFinished=True
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
"SOFTWARE\\WOW6432Node\\Valve\\Steam")
value = winreg.QueryValueEx(key, "InstallPath")[0]
steam_path = value + "\\Steam.exe"
currentDate=datetime.date.today().strftime("%Y-%m-%d")
finishedPath=f"finished-{currentDate}.json"
finishedData={}
if storeFinished:
try:
with open(finishedPath, 'r') as f:
finishedData = json.load(f)
except:
pass
alreadyProcessed=len(finishedData)
folderErrors=0
total=0
current=1
startTime = time.time()
with open("steamfolders.json", 'r') as f:
steamFolders = json.load(f)
for folder in steamFolders:
if os.path.isdir(folder):
for filename in os.listdir(folder):
if filename.endswith('.acf'):
total+=1
with open("steamfolders.json", 'r') as f:
steamFolders = json.load(f)
for folder in steamFolders:
if os.path.isdir(folder):
ProcessSteamFolder(folder)
else:
folderErrors+=1
endTime = time.time()
elapsedTime = endTime - startTime
print(f'Работа завершена, время '+formatTime(elapsedTime)+f', всего игр {len(finishedData)}, пропущено {alreadyProcessed}, ошибок пути {folderErrors}.')
Комментариев нет:
Отправить комментарий