Skip to content

Commit

Permalink
Add "Junk" removal switch to BCU-Console (#581)
Browse files Browse the repository at this point in the history
Adds option for BCU-Console to perform junk removal with a /J=<Level> switch.
  • Loading branch information
nixuno authored May 10, 2024
1 parent db1c187 commit a888058
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
2 changes: 1 addition & 1 deletion doc/BCU_manual.html

Large diffs are not rendered by default.

Binary file modified doc/BCU_manual.odt
Binary file not shown.
55 changes: 52 additions & 3 deletions source/BCU-console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Apache License Version 2.0
*/

using Klocman.Extensions;
using System;
using System.Collections.Generic;
using System.Globalization;
Expand All @@ -13,6 +14,9 @@ Apache License Version 2.0
using System.Threading;
using UninstallTools;
using UninstallTools.Factory;
using UninstallTools.Junk;
using UninstallTools.Junk.Confidence;
using UninstallTools.Junk.Containers;
using UninstallTools.Lists;
using UninstallTools.Uninstaller;

Expand All @@ -24,7 +28,7 @@ private static void ShowHelp()
{
Console.WriteLine(@"BCU-console [help | /?] - Show help (this screen)
BCU-console uninstall [drive:][path]filename [/Q] [/U] [/V] - Uninstall applications.
BCU-console uninstall [drive:][path]filename [/Q] [/U] [/V] [/J=<Level>] - Uninstall applications.
[drive:][path] – Specifies drive and directory of the uninstall list.
filename – Specifies filename of the .bcul uninstall list that contains information about
what applications to uninstall.
Expand All @@ -40,6 +44,10 @@ what applications to uninstall.
/U - Unattended mode (do not ask user for confirmation). WARNING: ONLY USE AFTER
THOROUGH TESTING. UNINSTALL LISTS SHOULD BE AS SPECIFIC AS POSSIBLE TO AVOID
FALSE POSITIVES. THERE ARE NO WARRANTIES, USE WITH CAUTION.
/J=<Level> - Attempt to clean up leftover ""junk"" (Registry entries and files/folders) after
uninstall. If no level is passed then defaults to ""VeryGood"". ***WARNING***: USE
EXTREME CAUTION WHEN CHOOSING ANY LEVEL BELOW VeryGood. THERE ARE NO WARRANTIES.
Valid levels are: VeryGood, Good, Questionable, Bad, Unknown
/V - Verbose logging mode (show more information about what is currently happening).
Return codes:
Expand Down Expand Up @@ -178,13 +186,28 @@ private static int ProcessUninstallCommand(string[] args)
var isQuiet = args.Any(x => x.Equals("/Q", StringComparison.OrdinalIgnoreCase));
var isUnattended = args.Any(x => x.Equals("/U", StringComparison.OrdinalIgnoreCase));

int junkArgumentIndex = Array.FindIndex(args, a => a.Equals("/J", StringComparison.OrdinalIgnoreCase));
string junkArg = args.Where(a => a.Equals("/J", StringComparison.OrdinalIgnoreCase) || a.StartsWith("/J=", StringComparison.OrdinalIgnoreCase)).FirstOrDefault() ?? string.Empty;
ConfidenceLevel? junkConfidenceLevel = null;
if(junkArg.IsNotEmpty()) {
string[] junkSplit = junkArg.Split('=', 2);
junkConfidenceLevel = ConfidenceLevel.VeryGood;
if (junkSplit.Length == 2) {
if (!Enum.TryParse(junkSplit[1], out ConfidenceLevel parsedJunkConfidenceLevel)) {
Console.WriteLine($"An invalid junk confidence level was passed: {junkSplit[1]}");
ShowHelp();
return 1;
}
junkConfidenceLevel = parsedJunkConfidenceLevel;
}
}
if (isUnattended)
Console.WriteLine(@"WARNING: Running in unattended mode. To abort press Ctrl+C or close the window.");

return RunUninstall(list, isQuiet, isUnattended, isVerbose);
return RunUninstall(list, isQuiet, isUnattended, isVerbose, junkConfidenceLevel);
}

private static int RunUninstall(UninstallList list, bool isQuiet, bool isUnattended, bool isVerbose)
private static int RunUninstall(UninstallList list, bool isQuiet, bool isUnattended, bool isVerbose, ConfidenceLevel? junkConfidenceLevel = null)
{
Console.WriteLine(@"Starting bulk uninstall...");
var apps = QueryApps(isQuiet, isUnattended, isVerbose);
Expand Down Expand Up @@ -243,6 +266,32 @@ private static int RunUninstall(UninstallList list, bool isQuiet, bool isUnatten
while (!isDone)
Thread.Sleep(250);

if (junkConfidenceLevel is not null) {
Console.WriteLine($"Starting junk cleanup with a minimum confidence level of {junkConfidenceLevel}");
List<IJunkResult> remainingJunk = JunkManager.FindJunk(apps, apps, _ => { })
.Where(j => j.Confidence.GetConfidence() >= junkConfidenceLevel)
.ToList();

if (!remainingJunk.Any()) {
Console.WriteLine($"No remaining junk found for any target applications.");
return 0;
}

Console.WriteLine("The following junk items will be permanently deleted:");
remainingJunk.ForEach(Console.WriteLine);
if (!isUnattended) {
Console.WriteLine(@"Do you want to continue? [Y]es/[N]o");
if (Console.ReadKey(true).Key != ConsoleKey.Y)
return CancelledByUser();
}

foreach (ApplicationUninstallerEntry entry in apps) {
// ApplicationUninstallerEntry doesn't currently implement an equality operator so ToLongString() will do as an object "hash".
List<IJunkResult> appJunk = remainingJunk.Where(j => j.Application.ToLongString().Equals(entry.ToLongString())).ToList();
Console.WriteLine($"{entry.DisplayName} Junk - {appJunk.Count} Entries Found");
appJunk.ForEach(j => j.Delete());
}
}
return 0;
}

Expand Down

0 comments on commit a888058

Please sign in to comment.