(view source code of deltrash.cs as plain text)
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
namespace RobvanderWoude
{
class DelTrash
{
static readonly string progver = "1.05";
static int Main( string[] args )
{
#region Initialize Variables
int rc = 0;
long totalsize = 0;
int deleteditems = 0;
int accessdenieddirs = 0;
bool accessdenied = false;
bool confirm = false;
bool listonly = false;
bool progress = false;
bool quiet = false;
bool verbose = false;
RecycleFlags flags = RecycleFlags.RecycleNoSound;
string drive = null; // default: All drives
string windrive = Path.GetPathRoot( Environment.SystemDirectory );
#endregion Initialize Variables
#region Parse Command Line
if ( args.Length > 3 )
{
return ShowHelp( );
}
foreach ( string arg in args )
{
switch ( arg.ToUpper( ) )
{
case "/?":
return ShowHelp( );
case "/C":
if ( confirm )
{
return ShowHelp( "Duplicate command line switch /C" );
}
confirm = true;
break;
case "/L":
if ( listonly )
{
return ShowHelp( "Duplicate command line switch /L" );
}
listonly = true;
break;
case "/P":
if ( progress )
{
return ShowHelp( "Duplicate command line switch /P" );
}
progress = true;
break;
case "/Q":
if ( quiet )
{
return ShowHelp( "Duplicate command line switch /Q" );
}
if ( verbose )
{
return ShowHelp( "Switches /V and /Q are mutually exclusive" );
}
verbose = true;
break;
case "/V":
if ( verbose )
{
return ShowHelp( "Duplicate command line switch /V" );
}
if ( quiet )
{
return ShowHelp( "Switches /V and /Q are mutually exclusive" );
}
verbose = true;
break;
case "/W":
if ( drive != null )
{
if ( drive == windrive )
{
return ShowHelp( "Either specify a drive letter or use the /W switch, not both" );
}
else
{
return ShowHelp( "Duplicate drive specification {0} and {1}", drive, arg.ToUpper( ) );
}
}
drive = windrive;
break;
default:
bool validdrive = false;
DriveInfo[] alldrives = DriveInfo.GetDrives( );
foreach ( DriveInfo drvinf in alldrives )
{
if ( drvinf.Name.Equals( arg + "\\", StringComparison.OrdinalIgnoreCase ) )
{
if ( drvinf.DriveType == DriveType.Fixed ) // Local harddisks only
{
validdrive = true;
drive = arg.ToUpper( );
}
else
{
return ShowHelp( "Drive \"{0}\" is not a local harddisk", arg );
}
}
}
if ( !validdrive )
{
return ShowHelp( "Invalid command line argument \"{0}\"", arg );
}
break;
}
}
verbose = verbose || listonly;
if ( !confirm )
{
flags |= RecycleFlags.RecycleNoConfirmation;
}
if ( !progress )
{
flags |= RecycleFlags.RecycleNoProgressUI;
}
#endregion Parse Command Line
#region Verbose Output
if ( verbose )
{
foreach ( DriveInfo diskdrive in DriveInfo.GetDrives( ) )
{
if ( diskdrive.Name.StartsWith( drive, StringComparison.OrdinalIgnoreCase ) )
{
if ( diskdrive.DriveType == DriveType.Fixed ) // local harddisks only
{
string recyclebin = Path.Combine( diskdrive.Name, "$RECYCLE.BIN" );
if ( Directory.Exists( recyclebin ) )
{
long size = 0;
int items = 0;
string[] files = new string[0];
string[] folders = Directory.GetDirectories( recyclebin );
foreach ( string folder in folders )
{
try
{
// assuming any access denied will occur on the first directory level
files = Directory.GetFiles( folder, "*.*", SearchOption.AllDirectories );
foreach ( string file in files )
{
size += new FileInfo( file ).Length;
items++;
}
}
catch ( UnauthorizedAccessException )
{
accessdenied = true;
accessdenieddirs++;
}
}
if ( size > 129 )
{
if ( items == 1 )
{
Console.WriteLine( "Marking 1 file ({1}) from drive {2} for deletion", items, FormatBytes( size ), diskdrive.Name.Remove( 2 ) );
totalsize += size;
deleteditems += items;
}
else if ( items > 1 )
{
Console.WriteLine( "Marking {0} files ({1}) from drive {2} for deletion", items, FormatBytes( size ), diskdrive.Name.Remove( 2 ) );
totalsize += size;
deleteditems += items;
}
}
}
}
}
}
}
#endregion Verbose Output
#region Actual Deletion
if ( listonly )
{
Console.WriteLine( "\n{0} items with a total size of {1} would have been deleted.", deleteditems, FormatBytes( totalsize ) );
}
else
{
uint result = SHEmptyRecycleBin( IntPtr.Zero, drive, flags );
if ( result == 0 )
{
if ( !quiet )
{
Console.WriteLine( "\n{0} items with a total size of {1} have been permanently deleted.", deleteditems, FormatBytes( totalsize ) );
if ( accessdenied )
{
if ( accessdenieddirs == 1 )
{
Console.WriteLine( "Not all items could be removed permanently because access was denied to 1 directory." );
}
else
{
Console.WriteLine( "Not all items could be removed permanently because access was denied to {0} directories.", accessdenieddirs );
}
}
}
rc = 0;
}
else
{
if ( !quiet )
{
Console.WriteLine( "\nNot all items could be removed permanently." );
}
rc = 1;
}
}
#endregion Actual Deletion
return rc;
}
static string FormatBytes( long bytes )
{
int KB = 1024;
int MB = 1024 * KB;
int GB = 1024 * MB;
if ( bytes < KB )
{
return bytes.ToString( ) + " B";
}
else if ( bytes < MB )
{
return ( bytes / KB ).ToString( ) + " KB";
}
else if ( bytes < GB )
{
return ( bytes / MB ).ToString( ) + " MB";
}
else
{
return ( bytes / GB ).ToString( ) + " GB";
}
}
static int ShowHelp( params string[] errmsg )
{
#region Error Message
if ( errmsg.Length > 0 )
{
List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
}
#endregion Error Message
#region Help Text
/*
DelTrash.exe, Version 1.04
Empty the Recycle Bin
Usage: DelTrash.exe [ drive: | /W ] [ /C ] [ /P ] [ /L | /Q | /V ]
Where: drive: empty recycle bin on this drive only
(default: all local harddisks)
/W empty recycle bin on Windows' drive only
(default: all local harddisks)
/C prompt for Confirmation
/L List only, do not delete
/P show Progress bar
/Q Quiet mode, no screen output
/V Verbose mode, show number of files and total size per disk drive
Notes: Switches /L and /Q and /V are mutually exclusive.
Return code is 0 if the Recycle Bin was emptied successfully, or 1
if there was nothing to delete or in case of (command line) errors.
Credits: Based on code by Vinoth Kumar
www.codeproject.com/Articles/20172/Empty-the-Recycle-Bin-using-C
Number of items and size calculation based on
Written by Rob van der Woude
https://www.robvanderwoude.com
*/
#endregion Help Text
#region Display Help Text
Console.Error.WriteLine( );
Console.Error.WriteLine( "DelTrash.exe, Version {0}", progver );
Console.Error.WriteLine( "Empty the Recycle Bin" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "DelTrash.exe [ drive: | /W ] [ /C ] [ /P ] [ /L | /Q | /V ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "drive:" );
Console.ResetColor( );
Console.Error.WriteLine( " empty recycle bin on this drive only" );
Console.Error.WriteLine( " (default: all local harddisks)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /W" );
Console.ResetColor( );
Console.Error.Write( " empty recycle bin on " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "W" );
Console.ResetColor( );
Console.Error.WriteLine( "indows' drive only" );
Console.Error.WriteLine( " (default: all local harddisks)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /C" );
Console.ResetColor( );
Console.Error.Write( " prompt for " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "C" );
Console.ResetColor( );
Console.Error.WriteLine( "onfirmation" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /L L" );
Console.ResetColor( );
Console.Error.WriteLine( "ist only, do not delete" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /P" );
Console.ResetColor( );
Console.Error.Write( " show " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "P" );
Console.ResetColor( );
Console.Error.WriteLine( "rogress bar" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /Q Q" );
Console.ResetColor( );
Console.Error.WriteLine( "uiet mode, no screen output" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /V V" );
Console.ResetColor( );
Console.Error.WriteLine( "erbose mode, show number of files and total size per disk drive" );
Console.Error.WriteLine( );
Console.Error.Write( "Notes: Switches " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/L" );
Console.ResetColor( );
Console.Error.Write( " and " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/Q" );
Console.ResetColor( );
Console.Error.Write( " and " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/V" );
Console.ResetColor( );
Console.Error.WriteLine( " are mutually exclusive." );
Console.Error.WriteLine( " Return code is 0 if the Recycle Bin was emptied successfully, or 1" );
Console.Error.WriteLine( " if there was nothing to delete or in case of (command line) errors." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Credits: Based on code by Vinoth Kumar" );
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Error.WriteLine( " www.codeproject.com/Articles/20172/Empty-the-Recycle-Bin-using-C" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Help Text
return 1;
}
public enum RecycleFlags : uint
{
RecycleNoConfirmation = 0x00000001,
RecycleNoProgressUI = 0x00000002,
RecycleNoSound = 0x00000004
}
[DllImport( "Shell32.dll", CharSet = CharSet.Unicode )]
static extern uint SHEmptyRecycleBin( IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags );
}
}
page last modified: 2024-04-16; loaded in 0.0124 seconds