66
77using DeepPurge . Core . App ;
88using DeepPurge . Core . Cleaning ;
9+ using DeepPurge . Core . Export ;
910using DeepPurge . Core . Diagnostics ;
1011using DeepPurge . Core . Drivers ;
1112using DeepPurge . Core . FileSystem ;
@@ -55,7 +56,7 @@ public static async Task<int> Main(string[] rawArgs)
5556 "uninstall" => await CmdUninstallAsync ( args , cts . Token ) ,
5657 "repair" => await CmdRepairAsync ( args , cts . Token ) ,
5758 "drivers" => await CmdDriversAsync ( args , cts . Token ) ,
58- "startup-impact" => CmdStartupImpact ( ) ,
59+ "startup-impact" => CmdStartupImpact ( args ) ,
5960 "shortcuts" => CmdShortcuts ( args ) ,
6061 "duplicates" => await CmdDuplicatesAsync ( args , cts . Token ) ,
6162 "snapshot" => await CmdSnapshotAsync ( args , cts . Token ) ,
@@ -206,7 +207,18 @@ private static async Task<int> CmdDriversAsync(ParsedArgs a, CancellationToken c
206207 {
207208 var pkgs = await new DriverStoreScanner ( ) . EnumerateAsync ( ct ) ;
208209 var oldOnly = a . HasFlag ( "old" ) ;
209- foreach ( var p in pkgs . Where ( p => ! oldOnly || p . IsOldVersion ) )
210+ var filtered = pkgs . Where ( p => ! oldOnly || p . IsOldVersion ) . ToList ( ) ;
211+
212+ var exportPath = a . GetOption ( "export" ) ;
213+ if ( exportPath != null )
214+ {
215+ var fmt = ParseExportFormat ( a ) ;
216+ GridExporter . ExportDrivers ( filtered , exportPath , fmt ) ;
217+ Console . WriteLine ( $ "Exported { filtered . Count } drivers to { exportPath } ") ;
218+ return 0 ;
219+ }
220+
221+ foreach ( var p in filtered )
210222 {
211223 var tag = p . IsOldVersion ? "OLD" : " " ;
212224 Console . WriteLine ( $ "[{ tag } ] { p . PublishedName , - 12 } { p . OriginalName , - 28 } { p . ProviderName , - 22 } { p . DriverVersion , - 30 } { FormatBytes ( p . SizeBytes ) } ") ;
@@ -215,7 +227,7 @@ private static async Task<int> CmdDriversAsync(ParsedArgs a, CancellationToken c
215227 return 0 ;
216228 }
217229
218- private static int CmdStartupImpact ( )
230+ private static int CmdStartupImpact ( ParsedArgs a )
219231 {
220232 var impacts = new StartupImpactCalculator ( ) . CalculateForCurrentUser ( ) ;
221233 if ( impacts . Count == 0 )
@@ -224,7 +236,17 @@ private static int CmdStartupImpact()
224236 Console . Error . WriteLine ( "Possible causes: ran without admin, or the system has not booted since WDI was enabled." ) ;
225237 return 1 ;
226238 }
227- foreach ( var e in impacts . Values . OrderByDescending ( e => ( int ) e . Impact ) . ThenByDescending ( e => e . DiskBytes ) )
239+ var sorted = impacts . Values . OrderByDescending ( e => ( int ) e . Impact ) . ThenByDescending ( e => e . DiskBytes ) . ToList ( ) ;
240+
241+ var exportPath = a . GetOption ( "export" ) ;
242+ if ( exportPath != null )
243+ {
244+ GridExporter . ExportStartupImpact ( sorted , exportPath , ParseExportFormat ( a ) ) ;
245+ Console . WriteLine ( $ "Exported { sorted . Count } entries to { exportPath } ") ;
246+ return 0 ;
247+ }
248+
249+ foreach ( var e in sorted )
228250 Console . WriteLine ( $ "{ e . Impact , - 6 } { e . ProcessName , - 32 } disk={ FormatBytes ( e . DiskBytes ) } cpu={ e . CpuMs } ms") ;
229251 return 0 ;
230252 }
@@ -234,6 +256,16 @@ private static int CmdShortcuts(ParsedArgs a)
234256 var scanner = new ShortcutRepairScanner ( ) ;
235257 var shortcuts = scanner . ScanAll ( ) ;
236258 var broken = shortcuts . Where ( s => s . Status == ShortcutStatus . Broken ) . ToList ( ) ;
259+
260+ var exportPath = a . GetOption ( "export" ) ;
261+ if ( exportPath != null )
262+ {
263+ var exportSet = a . HasFlag ( "all" ) ? shortcuts : broken ;
264+ GridExporter . ExportShortcuts ( exportSet , exportPath , ParseExportFormat ( a ) ) ;
265+ Console . WriteLine ( $ "Exported { exportSet . Count } shortcuts to { exportPath } ") ;
266+ return 0 ;
267+ }
268+
237269 foreach ( var s in broken ) Console . WriteLine ( $ "BROKEN { s . Path } -> { s . TargetPath } ") ;
238270 Console . WriteLine ( $ "# { broken . Count } broken of { shortcuts . Count } total") ;
239271 if ( a . HasFlag ( "delete" ) || a . HasFlag ( "recycle" ) )
@@ -251,6 +283,15 @@ private static async Task<int> CmdDuplicatesAsync(ParsedArgs a, CancellationToke
251283 : new [ ] { Environment . GetFolderPath ( Environment . SpecialFolder . UserProfile ) } ;
252284 var finder = new DuplicateFinder ( ) ;
253285 var groups = await finder . FindAsync ( roots , progress : new Progress < string > ( Console . Error . WriteLine ) , ct : ct ) ;
286+
287+ var exportPath = a . GetOption ( "export" ) ;
288+ if ( exportPath != null )
289+ {
290+ GridExporter . ExportDuplicates ( groups , exportPath , ParseExportFormat ( a ) ) ;
291+ Console . WriteLine ( $ "Exported { groups . Count } groups to { exportPath } ") ;
292+ return 0 ;
293+ }
294+
254295 foreach ( var g in groups )
255296 {
256297 Console . WriteLine ( $ "[{ FormatBytes ( g . WastedBytes ) } wasted, { g . Paths . Count } copies @ { FormatBytes ( g . FileSize ) } ]") ;
@@ -413,6 +454,12 @@ private static string FormatBytes(long bytes)
413454 return $ "{ b , 6 : F1} { u [ i ] } ";
414455 }
415456
457+ private static ExportFormat ParseExportFormat ( ParsedArgs a )
458+ {
459+ var fmt = a . GetOption ( "format" ) ? . ToLowerInvariant ( ) ;
460+ return fmt == "json" ? ExportFormat . Json : ExportFormat . Csv ;
461+ }
462+
416463 private static int Fail ( string msg ) { Console . Error . WriteLine ( msg ) ; return 2 ; }
417464
418465 private static bool IsHelp ( string a ) => a is "--help" or "-h" or "help" or "/?" ;
@@ -428,10 +475,10 @@ private static void PrintHelp()
428475 Console . WriteLine ( " uninstall <name> [--silent] Uninstall a program" ) ;
429476 Console . WriteLine ( " clean [junk|evidence ...] [--dry-run] [--secure]" ) ;
430477 Console . WriteLine ( " repair <sfc|dism-scan|dism-restore|dism-cleanup|dism-resetbase|chkdsk|fontcache|iconcache>" ) ;
431- Console . WriteLine ( " drivers [--old] List third-party drivers in DriverStore " ) ;
432- Console . WriteLine ( " startup-impact Show boot-time cost per process " ) ;
433- Console . WriteLine ( " shortcuts [--recycle] Scan Desktop/Start Menu for broken .lnk " ) ;
434- Console . WriteLine ( " duplicates [roots...] Find duplicate files " ) ;
478+ Console . WriteLine ( " drivers [--old] [--export file --format csv|json] " ) ;
479+ Console . WriteLine ( " startup-impact [--export file --format csv|json] " ) ;
480+ Console . WriteLine ( " shortcuts [--recycle] [--all] [--export file --format csv|json] " ) ;
481+ Console . WriteLine ( " duplicates [roots...] [--export file --format csv|json] " ) ;
435482 Console . WriteLine ( " snapshot trace <name> <installer> [--args \" ...\" ]" ) ;
436483 Console . WriteLine ( " winapp2 <path.ini> [--dry-run] Run community cleaner definitions" ) ;
437484 Console . WriteLine ( " schedule list" ) ;
@@ -468,7 +515,7 @@ public sealed class ParsedArgs
468515 // when you add a new command that needs them.
469516 private static readonly HashSet < string > ValueOptions = new ( StringComparer . OrdinalIgnoreCase )
470517 {
471- "name" , "freq" , "time" , "day" , "args" ,
518+ "name" , "freq" , "time" , "day" , "args" , "export" , "format" ,
472519 } ;
473520
474521 public bool HasFlag ( string name ) => Flags . Contains ( name ) ;
0 commit comments