曾经与Powershell战斗以做我需要做的事情。这可能是一个简单的解决方案,但我没有找到它。 如果这个问题重复出现,我会道歉,但是找不到我想要的答案。
TL; DR在底部。
所以,关于我的问题。 我正在尝试通过regedit将PS脚本添加到上下文菜单中,该脚本删除其中的文件夹+文件,它在其中没有任何空格的文件夹上效果很好,但是当我尝试删除有空格的文件夹(例如“ New Folder”)时,引发错误并关闭。 (试图通过Remove-Item寻找暂停/睡眠命令,但运气不好,除了长脚本有错误处理等)。
我怀疑错误类似于
Remove-Item : A positional parameter cannot be found that accepts argument 'Folder'.
在线:1个字符:12个 +删除项目<<<<新文件夹 + CategoryInfo:InvalidArgument:(:) [Remove-Item],ParameterBindingException + FullyQualifiedErrorId:PositionalParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
我当前使用的代码是
cmd /c PowerShell Remove-Item "%1" -recurse -force
我尝试过各种变体,以使其运气不佳。
即用“ pathAsString”替换"%1"
,添加另一个"% 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)。
可能是一个显而易见的解决方案,但我看不到。
答案 0 :(得分:0)
以下对我有用:
cmd /c PowerShell -command "& {Remove-Item -path '%1' -recurse -force -confirm:$false}"
使用cmd.exe时,没有脚本块之类的东西。这意味着传递给-command
的值将始终是字符串。我在('')
周围加上了单引号%1
,以使双引号("")
与您的论点保持一致。显然,如果文件路径中有单引号(')
,则此方法将失败。此外,即使在线文档中指出,也不需要呼叫运营商&
。
有关如何使用PowerShell.exe
的更多信息,请参见PowerShell.exe Command-Line Help。
请参阅About Quoting Rules,以获取有关PowerShell单引号和双引号如何工作的更多信息。
答案 1 :(得分:0)
您的尝试之一:
cmd /c PowerShell Remove-Item \"%1\" -recurse -force
实际上起作用,尽管只有那些具有嵌入空格的路径不包含 multiple 个相邻空格(请参阅底部的 first < / em>使用"%1"
而不是\"%1\"
的尝试无效)。
要使命令健壮(并提高效率),请使用以下变体,不涉及cmd.exe
(因为没有必要),并且传递给PowerShell的命令包含在"..."
整体 中,其中嵌入了 {{1} }以"
的身份转义(如您的尝试):
\"
使用的PowerShell CLI选项:
powershell.exe -noprofile -command "Remove-Item -LiteralPath \"%1\" -Recurse -Force"
禁止加载当前用户的配置文件(-noprofile
),这只会不必要地降低命令速度(或更糟糕的是,可能会更改其行为)。
$PROFILE
告诉PowerShell,其余参数是PowerShell命令(一段源代码,与-command
不同,后者用于调用 script )
-file
,因为它暗示了 ,而在PowerShell Core 中已不再是这种情况,默认为-command
。 -file
命令传递给PowerShell:
在Remove-Item
中包含 entire PowerShell命令可确保命令内的空格按原样保留,这与发生在以下位置的路径有关包含多个空格的运行,例如"..."
"c:\Users\jdoe\Invoices<space><space>2018"
是PowerShell要求嵌套(嵌入)\"
字符的方式。 使用"
从命令行调用时会被转义-参见以下说明。
-command
确保-LiteralPath
将字面意义解释为 而不是通配符模式(默认情况下,隐含的Remove-Item
参数);虽然不太可能,但如果将-Path
之类的路径当作通配符,则会破坏该命令。
注意事项:
由于(最终)使用了双引号(c:\tmp\folder[]
)来封闭路径(文件资源管理器将"..."
扩展到的目录路径),它变成了可扩展字符串< / em>,即受字符串内插约束,这意味着包含%1
个字符(例如$
)的文件夹路径可能会被误解。
您可以通过将c:\tmp\$foo
替换为\"%1\"
来抑制此插值,即使用单引号字符串(PowerShell始终按字面意义对待),但是问题是您将无法在路径恰好具有'%1'
个字符的文件夹上使用该命令。在它们中(例如'
)
c:\tmp\o'reilly
还不够: "%1"
(您的(第一条)命令行(您将其用作文件资源管理器上下文菜单的命令定义))如下处理:
“文件资源管理器”将cmd /c PowerShell Remove-Item "%1" -recurse -force
替换为右键单击的文件夹的文件的绝对路径,即按原样显示该路径是否包含空格;例如:
%1
。然后执行结果命令行;例如:
c:\Users\jdoe\Invoices 2018
cmd /c PowerShell Remove-Item "c:\Users\jdoe\Invoices 2018" -recurse -force
在这里是偶然的(并且不是必需的):它实际上只是将命令行中继到PowerShell(通过其可执行文件cmd /c
);例如:
powershell.exe
PowerShell first 处理各个参数-的powershell.exe Remove-Item "c:\Users\jdoe\Invoices 2018" -recurse -force
,Remove-Item
,"c:\Users\jdoe\Invoices 2018"
,-recurse
删除封闭的双引号 。
由于隐含-force
选项,因此将 quote-stripped 参数重新连接在一起,并以空格作为分隔符,然后 then 解释为PowerShell源代码的片段 ;例如:
-command
如您所见,双引号的删除导致PowerShell命令损坏,因为带空格的路径现在缺少引号,因此Remove-Item c:\Users\jdoe\Invoices 2018 -recurse -force
不再被识别为单< / em>参数,并被解释为 2 参数,前缀c:\Users\jdoe\Invoices 2018
后跟c:\Users\jdoe\Invoices
是它自己的语法无关参数。
同时使用2018
而不是\"%1\"
可以防止前期报价剥离-通过告诉PowerShell "%1"
字符。将在初始参数解析期间被保留-另外,为了正确保留具有多个相邻空格的文件路径,必须在"
中包含 entire PowerShell命令 / em>(即使此类路径可能是文件夹创建过程中输入错误的结果)
总体上不包含"..."
的情况下,用"..."
引用的路径(例如\"
)将导致以下 2 参数:
C:\Users\jdoe\Invoices<space><space>2018
\"C:\Users\jdoe\Invoices
2018\"
识别为转义的 \"
之后, (保留 ),将解释为PowerShell代码之前,它将看到"
,即只有单个空间。 / li>
总体上包含"C:\Users\jdoe\Invoices<space>2018"
,整个PowerShell命令被解析为单个参数,而内部空格按原样保留,可以避免此问题。