繁体   English   中英

Powershell删除项%1(上下文菜单)

[英]Powershell Remove-Item %1 (Context Menu)

一直在与Powershell战斗以完成我需要做的事情。 这可能是一个简单的解决方案,但我没有找到它。 如果这个问题重复,我会道歉,但是找不到我想要的答案。

TL; DR在底部。

所以,对于我的问题。 我正在尝试通过regedit将PS脚本添加到上下文菜单中,该脚本删除其中的文件夹+文件,它在其中没有任何空格的文件夹上效果很好,但是当我尝试删除有空格的文件夹(例如“ New Folder”)时,引发错误并关闭。 (试图通过Remove-Item查找暂停/睡眠命令,但是运气不好,除了长脚本有错误处理等)。

我怀疑错误类似于

Remove-Item : A positional parameter cannot be found that accepts argument 'Folder'.

在第1行:char:12 +删除项<<<<新文件夹+ CategoryInfo:InvalidArgument:(:) [Remove-Item],ParameterBindingException + FullyQualifiedErrorId:PositionalParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand

我当前使用的代码是

cmd /c  PowerShell Remove-Item "%1" -recurse -force

我尝试了各种变体,使其无法正常运行。 IE将"%1"替换为“ pathAsString”,添加了另一个"% 1" ,添加了通配符"* *" ,并删除了这些标志。 我尝试过的代码有一些不同的变化:

cmd /c PowerShell Remove-Item \"%1\" -recurse -force
cmd /c PowerShell Remove-Item & "{"%1" -recurse -force"}"

TL; DR cmd /c PowerShell Remove-Item "%1" -recurse -force忽略带有空格的文件夹,并尝试了各种操作。 上下文菜单中的用法(通过Regedit)。

可能是一个显而易见的解决方案,但我没有看到。

以下为我工作:

cmd /c PowerShell -command "& {Remove-Item -path '%1' -recurse -force -confirm:$false}"

使用cmd.exe时,没有脚本块之类的东西。 这意味着传递给-command的值将始终是字符串。 我在%1周围添加了单引号('') ,以将双引号("")与参数一起使用。 显然,如果文件路径中带有单引号(') ,则此方法将失败。 此外,即使在线文档中说明了,也不需要呼叫运营商&

有关如何使用PowerShell.exe更多信息,请参见PowerShell.exe命令行帮助

有关PowerShell单引号和双引号如何工作的更多信息,请参见关于报价规则

您的尝试之一:

cmd /c PowerShell Remove-Item \\"%1\\" -recurse -force

确实有效,尽管只有那些具有嵌入式空格的路径不包含多个相邻空格(请参阅底部,了解为什么您第一次尝试使用"%1"而不是\\"%1\\"无效)。

为了使命令强劲 (也更有效),使用下面的变化,这涉及cmd.exe (因为它是没有必要的),并命令传递给PowerShell是封闭在"..." 作为整体带有嵌入的"转义为\\" (如您的尝试):

powershell.exe -noprofile -command "Remove-Item -LiteralPath \"%1\" -Recurse -Force"

使用的PowerShell CLI选项:

  • -noprofile禁止加载当前用户的配置文件( $PROFILE ),这只会不必要地减慢该命令的速度(或者更糟的是,可以更改其行为)。

  • -command告诉PowerShell其余参数是PowerShell命令(一段源代码,与-file不同,后者用于调用脚本

    • 尽管您不必严格要求在Windows PowerShell中指定-command ,因为它隐含了该内容,但在PowerShell Core中已不再是这种情况,默认情况下,该属性为-file

传递给PowerShell的Remove-Item命令:

  • 整个 PowerShell命令括在"..."可确保命令内的空格按原样保留 ,这与碰巧包含多个空格的运行路径有关,例如"c:\\Users\\jdoe\\Invoices<space><space>2018"

  • \\"是PowerShell如何需要嵌套 (嵌入) "字符。 使用-command 从命令行调用时 ,可以使用-进行转义 -有关说明,请参见下文。

  • -LiteralPath确保Remove-Item字面方式解释路径,而不是将其解释为通配符模式 (默认情况下会使用隐含的-Path参数); 虽然不太可能,但是如果将c:\\tmp\\folder[]这样的路径用作通配符,则会破坏该命令。

注意事项

  • 由于(最终)使用双引号( "..." )括住路径(文件资源管理器将%1扩展到的目录路径),因此它变成了可扩展的字符串 ,即受到字符串插值的影响 ,这意味着包含$字符的文件夹路径(例如c:\\tmp\\$foo )可能会被误解。

  • 您可以通过将\\"%1\\"替换为'%1'来抑制这种插值,即使用单引号引起来的字符串(PowerShell始终按字面意义对待),但是问题是您将无法使用路径碰巧带有'字符的文件夹上的命令。 在它们中(例如c:\\tmp\\o'reilly


为什么仅使用"%1"还不够:

cmd /c PowerShell Remove-Item "%1" -recurse -force (您的(第一条)命令行(您将其用作File Explorer上下文菜单命令定义 ))的处理如下:

  • “文件资源管理器”按原样-用右键单击的文件夹的文件绝对路径替换%1路径是否包含嵌入的空格; 例如:

    • c:\\Users\\jdoe\\Invoices 2018
  • 然后执行结果命令行; 例如:

    • cmd /c PowerShell Remove-Item "c:\\Users\\jdoe\\Invoices 2018" -recurse -force
  • cmd /c在这里是偶然的(不需要):它实际上只是将命令行中继到PowerShell(通过其可执行文件powershell.exe ); 例如:

    • powershell.exe Remove-Item "c:\\Users\\jdoe\\Invoices 2018" -recurse -force
  • PowerShell 首先通过删除双引号来处理各个参数Remove-Item"c:\\Users\\jdoe\\Invoices 2018"-recurse-force

  • 由于隐含了-command选项,因此将使用引号分隔的参数重新连接,并使用空格作为分隔符, 然后将其解释为PowerShell源代码片段 例如:

    • Remove-Item c:\\Users\\jdoe\\Invoices 2018 -recurse -force

    • 如您所见,双引号的删除导致PowerShell命令损坏,因为带有空格的路径现在缺少引号,因此c:\\Users\\jdoe\\Invoices 2018不再被视为单个参数,而是被解释为2个参数,前缀c:\\Users\\jdoe\\Invoices后跟2018作为语法上无关的参数。

    • 当使用\\"%1\\" ,而不是"%1"单独将阻止的前期报价剥离-告诉PowerShell中,所述"字符是初始参数解析过程中要保留 - 。另外包围在整个PowerShell命令 "..."对于正确保留多个相邻空间的文件路径是必要的(即使这些路径可能是文件夹创建过程中输入错误的结果):

      • 如果不整体包含"..." ,则使用\\"引号的路径(例如C:\\Users\\jdoe\\Invoices<space><space>2018将导致以下两个参数:

        • \\"C:\\Users\\jdoe\\Invoices
        • 2018\\"
        • 当PowerShell稍后在各个参数之间用单个空格重新连接时(在将\\"识别为要保留转义" ), 将结果字符串解释为PowerShell代码之前,它将看到"C:\\Users\\jdoe\\Invoices<space>2018" ,即,仅一个单一的空间。
      • 随着整体封闭"..." ,整个PowerShell命令被解析为一个单独的参数,与室内空白保留原样 ,避免了这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM