如何在Windows批处理脚本或Perl中将文件移动到回收站?

时间:2023-01-15 12:46:06

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?

我有一个Windows XP批处理脚本清理一些目录,但我想将删除的文件移动到垃圾桶而不是使用普通的del。这是怎么做到的?

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

看起来我可以使用的唯一语言是普通批处理或Perl。

5 个解决方案

#1


use Win32::FileOp qw(Recycle);
Recycle(@ARGV);

#2


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

编写VBS脚本(原始链接),然后使用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");
}

#3


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

Win32 :: FileOp模块具有回收功能。来自文档:

Recycle @filenames

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

将文件发送到回收站。您将不会收到任何确认对话框。如果成功则返回true。

#4


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

您可以使用“回收”实用程序,该实用程序是MaDdoG Software的CmdUtils的一部分。从页面列表 -

  • 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!)
  • Recycle,DEL命令的安全替代品,用于将文件发送到回收站而不是删除它们。回收也比DEL更灵活;你可以一次指定多个文件(或使用通配符),你可以一次回收整个目录(小心!)

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.

我建议你在将它们合并到你的脚本之前尝试它的各种开关 - 这与“del”命令的默认行为有很大的不同。

#5


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.

更新:与我最初声称以下代码不起作用相反,它确实似乎有效。我忘记了我想要删除的文件不在$ ENV {TEMP}中,而是$ ENV {TEMP}的子目录。问题是,该文件不会转到回收站。

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:

正确的解决方案是使用Win32 :: FileOp,但我将把这个脚本留在这里作为如何使用Win32 :: API和Win32 :: API :: Struct的示例。如果有人能指出我做错了什么,我将不胜感激。供你参考:

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__

#1


use Win32::FileOp qw(Recycle);
Recycle(@ARGV);

#2


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

编写VBS脚本(原始链接),然后使用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");
}

#3


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

Win32 :: FileOp模块具有回收功能。来自文档:

Recycle @filenames

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

将文件发送到回收站。您将不会收到任何确认对话框。如果成功则返回true。

#4


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

您可以使用“回收”实用程序,该实用程序是MaDdoG Software的CmdUtils的一部分。从页面列表 -

  • 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!)
  • Recycle,DEL命令的安全替代品,用于将文件发送到回收站而不是删除它们。回收也比DEL更灵活;你可以一次指定多个文件(或使用通配符),你可以一次回收整个目录(小心!)

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.

我建议你在将它们合并到你的脚本之前尝试它的各种开关 - 这与“del”命令的默认行为有很大的不同。

#5


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.

更新:与我最初声称以下代码不起作用相反,它确实似乎有效。我忘记了我想要删除的文件不在$ ENV {TEMP}中,而是$ ENV {TEMP}的子目录。问题是,该文件不会转到回收站。

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:

正确的解决方案是使用Win32 :: FileOp,但我将把这个脚本留在这里作为如何使用Win32 :: API和Win32 :: API :: Struct的示例。如果有人能指出我做错了什么,我将不胜感激。供你参考:

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__