Last active
April 5, 2020 22:19
-
-
Save GENiEBEN/558bb280d75334853eb74267032b36d7 to your computer and use it in GitHub Desktop.
Finds left-over folders from uninstalled Steam games.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;============================================================================================================ | |
;DeadGames script 2020.04.05 | |
;https://github.com/GENiEBEN | |
;============================================================================================================ | |
;This script will detect which Steam games have left folders behind after uninstallation by assuming any game | |
;folder without an .exe (recursive) is no longer a playable/installed game. TODO:Linux/Mac support. | |
;Please place it in the prefered Steam library, under the \steamapps\common\ folder. | |
;Default behaviour is to rename the folders by adding _ as a prefix and to delete completely empty folders. | |
;============================================================================================================ | |
#NoEnv | |
SendMode Input | |
SetWorkingDir %A_ScriptDir% | |
Games := "" | |
Rubbish := "" | |
Log := "" | |
ShortLog := "" | |
;Convert bytes to something more readable | |
StrFormatByteSizeEx(int) | |
{ | |
static size := StrLen(buf := "0123456789ABCDEF") | |
if !(pstr := DllCall("shlwapi.dll\StrFormatByteSize64A", "int64", int, "str", buf, "uint", size, "astr")) | |
throw Exception("StrFormatByteSize64 failed: " pstr, -1) | |
return pstr | |
} | |
;Create a list of root folders (our games) | |
Loop, *.*, 2 | |
Games .= A_LoopFileName "`n" | |
Sort, Games, R | |
;Go through each game | |
Loop, parse, Games, `n | |
{ | |
counter = 0 | |
if (A_LoopField = "") | |
continue | |
;Look for executables | |
Loop Files, %A_LoopField%\*.exe, R | |
{ | |
counter += 1 | |
break | |
} | |
;We had no exe, game is probably uninstalled | |
if counter = 0 | |
{ | |
Rubbish .= A_LoopField "`n" | |
;Rename folders with a few files left. | |
FileMoveDir, %A_LoopField%, _%A_LoopField%, R ;Rename folder with a prefix | |
} | |
} | |
;Optional: Calculate size of "dead" games and generate a log | |
Total := 0 | |
Savings := 0 | |
Loop, parse, Rubbish, `n | |
{ | |
Position := A_Index | |
if (A_LoopField = "") | |
continue | |
;Remove game log files, this should leave behind only more important folders (i.e. containing savegames) | |
Loop Files, _%A_LoopField%\output_log.txt, R ;typical log files in Unity games | |
FileDelete, %A_LoopFileFullPath% | |
Loop Files, _%A_LoopField%\debug.log, R ;typical log files in NodeWebkit games | |
FileDelete, %A_LoopFileFullPath% | |
;Get size of a folder | |
FolderSize := 0 | |
Loop, _%A_LoopField%\*.*, , 1 | |
FolderSize += A_LoopFileSize | |
Savings += FolderSize | |
;Delete completely empty folder. TODO:Won't delete folder if it had a log file that was removed | |
if (FolderSize = 0) | |
FileRemoveDir, _%A_LoopField% | |
;Keep a log of folders found | |
Log .= StrFormatByteSizeEx(FolderSize) " | " A_LoopField "`n" | |
if (Position < 11) | |
ShortLog .= StrFormatByteSizeEx(FolderSize) " | " A_LoopField "`n" | |
Total += 1 | |
} | |
;Sort A-Z our logs TODO:Should sort by bytes first | |
Sort, Log, R | |
Sort, ShortLog, R | |
Log .= "`nThere were " Total " games with leftover files, using a total of " StrFormatByteSizeEx(Savings) | |
if (Position > 10) | |
ShortLog .= "`n ...and " . Total-10 . " more. Check DeadGames.log for details" | |
;Write log file and display results dialog to user | |
FileDelete, DeadGames.log | |
FileAppend, %Log%, DeadGames.log | |
if (!Rubbish = "") | |
MsgBox % "Following folders have been renamed and are`nsafe to remove, saving you a potential " StrFormatByteSizeEx(Savings) "`n`n" ShortLog | |
Else | |
MsgBox % "There was nothing to clean, amazing!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment