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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1062808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:44:14  来源:igfitidea点击:

How can I move files to the Recycle Bin in a Windows batch script or Perl?

windowsperlbatch-file

提问by l0b0

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。

回答by FMc

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

回答by Shay Erlichmen

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");
}

回答by Chas. Owens

The Win32::FileOpmodule has a Recyclefunction. From the docs:

Win32的:: FileOp模块具有Recycle的功能。从文档:

Recycle @filenames

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

回收@filenames

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

回答by Sinan ünür

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 subdirectoryof $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::FileOpbut I am going to leave this script here as an example of how to use Win32::APIand Win32::API::Struct. I would appreciate it if anyone can point out what I am doing wrong. For your reference:

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

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

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

LPSHFILEOPSTRUCT: http://msdn.microsoft.com/en-us/library/bb759795(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 . "
<!-- : 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>
echo This file is dirt.> dirt.txt
echo This file is trash.> trash.txt
recycle dirt.txt trash.txt
"; 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__

回答by giraffe

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

它可以通过普通批处理和嵌入式 VBScript 来完成。将以下代码放入名为 的文件中recycle.cmd

##代码##

Example:

例子:

##代码##

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).

在批处理文件中嵌入 VBScript 的想法取自 dbenham 的回答,是否可以在不使用临时文件的情况下在批处理文件中嵌入和执行 VBScript?(向下滚动到更新 2014-04-27)。

回答by aks

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

您可以使用“回收”的工具,它是一部分CmdUtilsMaDdoG软件。从页面列表 -

  • 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 命令的安全替代品,它将文件发送到回收站而不是删除它们。Recycle 也比 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”命令的默认行为有很大的偏差。