【问题标题】:Converting batch file to powershell with special characters in path使用路径中的特殊字符将批处理文件转换为powershell
【发布时间】:2019-12-16 01:24:05
【问题描述】:

我很难编写一个简单的批处理文件作为 powershell 脚本。

考虑这个文件夹结构。注意里面有很酷的[1] 的目录...

exiftool.exe
是一个命令实用程序,用于(例如)从嵌入的 MP3 标签中提取图片。
如果您需要更多信息,我uploaded its help

oldscript.cmd
exiftool -picture -b input.mp3 > output.jpg
这一行是在 powershell 中编写的行。我在作者的forum post 中找到了语法

  • -picture 代表要提取的标签,-b 代表二进制模式
  • input.mp3 是我的测试 mp3,它的路径中可以包含特殊字符,例如 [ 和 ]​​i>
  • > output.jpg 定义名称并将生成的图像保存在同一文件夹中

newscript.ps1
我目前最好的非工作代码是:

$ownpath = Split-Path $MyInvocation.MyCommand.Path
$exe = $ownpath + '\exiftool.exe'
$input = $ownpath + '\input.mp3'
$outimg = $ownpath + '\output.jpg'    

& $exe -picture -binary $input| Set-Content -literalPath $outimg -encoding UTF8

我发现Set-Content 能够通过“-literalpath”处理路径中的特殊字符。但我仍然无法将批处理转换为 Powershell 脚本,因为 与旧的批处理管道(“>”)相比,Set-Content(以及 Out-File 方法)似乎工作不同。无论我使用哪种编码,都无法查看生成的图像。 help file from above 表示 exiftool 使用的是 UTF8 编码。

当然,我尝试了其他available encodings,但它们都未能生成可视图像。我被困在这一点上。所以我最初的问题仍然部分存在“如何将此批处理文件转换为 powershell”。

那么为什么使用旧的批处理命令会起作用?

例如:创建一个文件夹“D:folder”并将此MP3 file with a cover image 放入其中。
从上面下载exiftool.exe并将其也放在那里。

旧的批处理命令将起作用并为您提供可见的图像

D:\folder\exiftool -picture -binary D:\folder\input.mp3 > D:\folder\output.jpg

具有相同语法的新 Powershell V2 脚本将失败。为什么?

& D:\folder\exiftool.exe -picture -binary D:\folder\input.mp3 > D:\folder\output.jpg

【问题讨论】:

    标签: batch-file powershell-2.0 command-line-arguments


    【解决方案1】:

    你可以试试这个,虽然我没有测试过,因为我没有嵌入图像的 mp3:

    $file = & "D:\folder\exiftool.exe" -picture -binary "D:\folder\input.mp3"
    
    [io.file]::WriteAllBytes('D:\folder\input[1].jpg',$file)
    

    编辑:

    使用 powershell 控制台中的这一行返回一个可读的图像:

     cmd.exe /c "D:\folder\exiftool.exe -picture -binary `"D:\folder\input.mp3`" > image.jpg"
    

    您可以在路径和文件名中使用特殊字符:

     $exe = "c:\ps\exiftool.exe"
     $mp3 = "c:\ps\a[1]\input.mp3" 
     $jpg = " c:\ps\a[1]\image[1].jpg"
    
     cmd.exe /c "$exe -picture -binary $mp3 > $jpg"
    

    路径内有空格:

     $exe = "c:\ps\exiftool.exe"
     $mp3 = "`"c:\ps\a [1]\input.mp3`"" 
     $jpg = "`"c:\ps\a [1]\image [1].jpg`""
    
     cmd.exe /c "$exe -picture -binary $mp3 > $jpg"
    

    【讨论】:

    • 测试过了。给出错误Cannot convert argument "1", with value: "System.Object[]", for "WriteAllBytes" to type "System.Byte[]": "Cannot convert value " ╪ α JFIF █ ä " to type "System.Byte". Error: "Input string was not in a correct format."" 这是一个example MP3 如果你需要它来测试。
    • @nixda 感谢 mp3 示例。我在答案中找到了替代代码。
    • 关闭一个。在 "a[1]" » "a [1]" 中插入一个空格,它将不起作用。我猜变量需要用双引号引起来。但是怎么做呢?
    • 稍作修改即可使用。看我的回答。如果没有人提出真正的 Powershell V2 解决方案,我将在几天后接受您的答复。非常感谢。
    【解决方案2】:

    试试这个:

    & $exe -picture -b $input | Out-File -LiteralPath $output
    

    使用 Start-Process 无需使事情复杂化。因为您计算了 exe 的路径并将结果放入字符串中,所以您只需要使用调用运算符 & 来调用由其后面的字符串命名的命令。

    【讨论】:

    • 你测试过吗?因为输出文件doesn't understand -LiteralPath。即使我删除了特殊字符[1],也会创建输出文件但无法查看。如果从批处理调用该工具,但不能从 PS 调用。
    • 请看我的编辑。我更进一步使用 Set-Content,它在 V2 中也有文字路径。但是与旧的 Windows 批处理和使用 ">" 的管道相比,结果文件的处理方式有所不同
    • IIRC v3 修复了许多 LiteralPath 问题。
    【解决方案3】:

    这是一个解决方法。看来您无法完全避免使用旧的 cmd.exe。
    谢谢应该去@C.B.

    $ownpath = Split-Path $MyInvocation.MyCommand.Path
    $exe = $ownpath + '\exiftool.exe'
    $input = $ownpath + '\input.mp3'
    $output = $ownpath + '\output.jpg'
    
    cmd.exe /c " `"$exe`" -picture -binary `"$input`" > `"$output`" "
    

    注意:

    • 这样所有路径都可以包含特殊字符,例如 [ 和 ] 或空格
    • " `"$exe 中的额外空间很重要。没有它就行不通。

    set-contentOut-File(“>”是别名)和[io.file]::WriteAllBytes 的普通 Powershell 方式都不适用于 exiftool.exe 实用程序。对我来说这是一个奇迹。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 2012-01-10
      • 2016-08-11
      • 1970-01-01
      • 2011-10-06
      • 2018-02-08
      相关资源
      最近更新 更多