Skip to content

Instantly share code, notes, and snippets.

@GENiEBEN
Last active April 5, 2020 22:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GENiEBEN/558bb280d75334853eb74267032b36d7 to your computer and use it in GitHub Desktop.
Save GENiEBEN/558bb280d75334853eb74267032b36d7 to your computer and use it in GitHub Desktop.
Finds left-over folders from uninstalled Steam games.
;============================================================================================================
;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