Converting batch file to powershell with special c

2019-09-04 23:08发布

问题:

I'm having a hard time to write a simple batch file as powershell script.

Consider this folder structure. Note the directory with the cool [1] in it...

exiftool.exe
Is a command utility to (for example) extract pictures from embedded MP3 tags.
I uploaded its help if you need more info.

oldscript.cmd
exiftool -picture -b input.mp3 > output.jpg
This line is the one to write in powershell. I found the syntax in a forum post from the author

  • -picture stands for the tag to extract and -b stands for binary mode
  • input.mp3 is my test mp3 which can contain special characters in its path like [ and ]
  • > output.jpg defines the name and saves the resulting image in the same folder

newscript.ps1
My best current non-working code is:

$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

I found Set-Content which is able to handle special characters in pathes through "-literalpath". But I'm still not able to convert the batch to a Powershell script because Set-Content (and Out-File method too) seems work different compared to old batch piping (">"). The resulting image is not viewable regardless which encoding I use. The help file from above says that exiftool is using UTF8 encoding.

Of course I tried other available encodings, but all of them failed to produce a viewable image. I'm stuck at this point. So my initial question still stands partly "How do I convert this batch file to powershell".

So why is it working when using the old batch command?

For example: create a folder "D:folder" and place this MP3 file with a cover image in it.
Download exiftool.exe from above and place it there too.

The old batch command will work and give you a viewable image

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

The new Powershell V2 script with the same syntax will fail. Why?

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

回答1:

You can try this, though I've not tested it 'cause I've not an mp3 with embedded images:

$file = & "D:\folder\exiftool.exe" -picture -binary "D:\folder\input.mp3"

[io.file]::WriteAllBytes('D:\folder\input[1].jpg',$file)

Edit:

using this line from a powershell console return a readable image:

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

You can use special characters in path and in file name as:

 $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"

with spaces inside path:

 $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"


回答2:

Try this:

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

There is no need to complicate things by using Start-Process. Because you compute the path to the exe and put that result in a string, you only need use the call operator & to invoke the command named by the string that follows it.



回答3:

Here is a work around. It seems you can't avoid good old cmd.exe completely.
Thanks should go @ 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`" "

Note:

  • This way all pathes can contain special characters like [ and ] or spaces
  • That extra space in " `"$exe is important. It won't work without it.

The normal Powershell way with set-content, Out-File (">" is an alias) and [io.file]::WriteAllBytes all don't work with the exiftool.exe utility. For me its a miracle.