[英]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
不同,后者用于调用脚本 )
-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代码之前,它将看到"C:\\Users\\jdoe\\Invoices<space>2018"
,即,仅一个单一的空间。 随着整体封闭"..."
,整个PowerShell命令被解析为一个单独的参数,与室内空白保留原样 ,避免了这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.