7

I've got a Windows XP batch script which cleans some directories, but I would like to move the deleted files to trash instead of using plain del. How is this done?

It looks like the only languages I can use for this is plain batch or Perl.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
l0b0
  • 55,365
  • 30
  • 138
  • 223

6 Answers6

7
use Win32::FileOp qw(Recycle);
Recycle(@ARGV);
FMc
  • 41,963
  • 13
  • 79
  • 132
5

Write a VBS script (Original Link) then call it with MyDelScript.vbs

function main()
{
  if (WScript.Arguments.length != 1)
  {
    WScript.Echo("<Insert informative error message here>");
    return;
  }

  var Path = WScript.Arguments(0);
  var Shell = WScript.CreateObject("Shell.Application");
  var Item = Shell.Namespace(0).ParseName(Path);
  Item.InvokeVerb("delete");
}
Shay Erlichmen
  • 31,691
  • 7
  • 68
  • 87
  • I get an error message on Windows 7 when i run this vbs file. The message is "Line: 2, Char: 1, Error: Invalid character, Code:800A0408, Source:Microsoft VBScript compilation error". I've tried the suggestion here but it doesn't help http://stackoverflow.com/a/9217824/781695 – user Sep 16 '13 at 06:18
3

The Win32::FileOp module has a Recycle function. From the docs:

Recycle @filenames

Send the files into the recycle bin. You will not get any confirmation dialogs. Returns true if successful.

Chas. Owens
  • 64,182
  • 22
  • 135
  • 226
2

It can be done like this with plain batch and embedded VBScript. Put the following code into a file called recycle.cmd:

<!-- : Begin batch script
@echo off

if "%1"=="" (
  echo Usage: %~nx0 FILE_TO_RECYCLE[...]
  echo This script puts files into the recycle bin
  exit /b 1
)

cscript //nologo "%~f0?.wsf" %*
exit /b %errorlevel%

----- Begin embedded wsf script --->
<job><script language="VBScript">
Set app = WScript.CreateObject("Shell.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
For Each arg In WScript.Arguments
  If fso.FileExists(arg) Then
    Set file = fso.GetFile(arg)
    Set folderItem = app.Namespace(0).ParseName(file.Path)
    folderItem.InvokeVerb("delete")
  Else
    WScript.Echo "File not found: " & arg
  End If
Next
</script></job>

Example:

echo This file is dirt.> dirt.txt
echo This file is trash.> trash.txt
recycle dirt.txt trash.txt

As you can see the script allows recycling multiple files with one command. It does not suppport the wildcards * and ? though.

The idea of embedding VBScript inside a batch file is taken from dbenham's answer to Is it possible to embed and execute VBScript within a batch file without using a temporary file? (scroll down to UPDATE 2014-04-27).

giraffe
  • 165
  • 3
1

You could use the "recycle" utility which is part of CmdUtils from MaDdoG Software. From the page listing -

  • Recycle, a safe replacement for the DEL command, that sends files to the recycle bin instead of deleting them. Recycle is also more flexible than DEL; you can specify multiple files at once (or use wildcards), and you can recycle whole directories at once (be careful!)

I would suggest you try its various switches before you incorporate it into your script - there is quite a bit of deviation from the default behaviour of the "del" command.

aks
  • 24,359
  • 3
  • 32
  • 35
1

UPDATE: Contrary to my original claim that the following code does not work, it indeed seems to work. I just forgot that the file I wanted to delete was not in $ENV{TEMP} but a subdirectory of $ENV{TEMP}. The problem is, the file does not go to the Recycle Bin.

The right solution is to use Win32::FileOp but I am going to leave this script here as an example of how to use Win32::API and Win32::API::Struct. I would appreciate it if anyone can point out what I am doing wrong. For your reference:

SHFileOperation: http://msdn.microsoft.com/en-us/library/bb762164(VS.85).aspx

LPSHFILEOPSTRUCT: http://msdn.microsoft.com/en-us/library/bb759795(VS.85).aspx

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions qw( catfile );
use Win32::API;

Win32::API::Struct->typedef(
    SHFILEOPSTRUCT => qw(
        HWND hwnd;
        UINT wFunc;
        LPCTSTR pFrom;
        LPCTSTR pTo;
        FILEOP_FLAGS fFlags;
        BOOL fAnyOperationsAborted;
        LPVOID hNameMappings;
        LPCTSTR lpszProgressTitle;
    )
);

Win32::API->Import(
    shell32 => q{ int SHFileOperation( LPSHFILEOPSTRUCT lpFileOp ) }
);

my $op = Win32::API::Struct->new( 'SHFILEOPSTRUCT' );
$op->{wFunc}  = 0x0003; # FO_DELETE from ShellAPI.h
$op->{fFlags} = 0x0040; # FOF_ALLOWUNDO from ShellAPI.h

my $to_delete = catfile( $ENV{TEMP}, "test.file" );
$op->{pFrom}  = $to_delete . "\0\0";

my $result = SHFileOperation( $op );

if ( $result ) {
    warn sprintf "The operation failed: %4.4X\n", $result;
}
else {
    if ( $op->{fAnyOperationsAborted} ) {
        warn "Operation was aborted\n";
    }
    else {
        warn "The operation succeeded\n";
    }
}
__END__
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339