PowerShell / vscode-powershell

Provides PowerShell language and debugging support for Visual Studio Code
https://marketplace.visualstudio.com/items/ms-vscode.PowerShell
MIT License
1.69k stars 481 forks source link

Debugging a script that invokes exiftool.exe hangs #3225

Closed sba923 closed 2 years ago

sba923 commented 3 years ago

System Details

System Details Output

### VSCode version: 1.53.2 622cb03f7e070a9670c94bae1a45d78d7181fbd4 x64

### VSCode extensions:
af4jm.vscode-m3u@1.0.0
akamud.vscode-javascript-snippet-pack@0.1.6
alefragnani.Bookmarks@13.0.3
Angular.ng-template@11.2.4
anseki.vscode-color@0.4.5
anweber.vscode-tidyhtml@1.10.0
austin.code-gnu-global@0.2.2
chenxsan.vscode-standardjs@1.4.0
christian-kohler.npm-intellisense@1.3.1
christian-kohler.path-intellisense@2.3.0
CoenraadS.bracket-pair-colorizer@1.0.61
Damien.autoit@1.0.5
DavidAnson.vscode-markdownlint@0.39.0
DotJoshJohnson.xml@2.5.1
DougFinke.vscode-PSStackoverflow@0.0.2
ecmel.vscode-html-css@1.10.2
eg2.vscode-npm-script@0.3.16
esbenp.prettier-vscode@5.9.2
formulahendry.platformio@0.3.0
GrapeCity.gc-excelviewer@3.0.41
Gruntfuggly.todo-tree@0.0.199
hdg.live-html-previewer@0.3.0
HookyQR.beautify@1.5.0
humao.rest-client@0.24.4
infinity1207.angular2-switcher@0.3.3
ionutvmi.reg@1.0.2
jasonnutter.github-pr@1.0.0
leighlondon.eml@0.4.0
mechatroner.rainbow-csv@1.8.1
Mikael.Angular-BeastCode@10.0.3
ms-azure-devops.azure-pipelines@1.183.0
ms-dotnettools.csharp@1.23.9
ms-mssql.mssql@1.10.1
ms-python.python@2021.2.582707922
ms-toolsai.jupyter@2021.2.603412351
ms-vscode-remote.remote-wsl@0.53.4
ms-vscode.azure-account@0.9.6
ms-vscode.cpptools@1.2.2
ms-vscode.powershell@2021.2.2
ms-vscode.vscode-typescript-tslint-plugin@1.3.3
msjsdiag.debugger-for-chrome@4.12.12
natewallace.angular2-inline@0.0.17
nobuhito.printcode@3.0.0
nrwl.angular-console@17.0.0
oderwat.indent-rainbow@7.5.0
platformio.platformio-ide@2.3.0
quicktype.quicktype@12.0.46
RandomFractalsInc.geo-data-viewer@2.3.0
redhat.java@0.75.0
tht13.html-preview-vscode@0.2.5
twxs.cmake@0.0.17
Tyriar.lorem-ipsum@1.2.0
VisualStudioExptTeam.vscodeintellicode@1.2.11
vitaliymaz.vscode-svg-previewer@0.7.0
vscjava.vscode-java-debug@0.31.0
vscjava.vscode-java-dependency@0.18.1
vscjava.vscode-java-pack@0.12.1
vscjava.vscode-java-test@0.28.0
vscjava.vscode-maven@0.27.1
yzane.markdown-pdf@1.4.4
yzhang.markdown-all-in-one@3.4.0
Zignd.html-css-class-completion@1.20.0
zovorap.ab-html-formatter@0.0.2

### PSES version: 2.3.0.0

### PowerShell version:

Name                           Value
----                           -----
PSVersion                      7.1.2
PSEdition                      Core
GitCommitId                    7.1.2
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Issue Description

When I run the following script under the PowerShell debugger within VScode, it hangs when launching exiftool.exe:

$exiftool = (Get-Command exiftool).Path
Write-Host ("'exiftool' is '{0}' (version {1}) {{MD5={2}}}" -f $exiftool, (Get-Item $exiftool).VersionInfo.ProductVersion, (Get-Filehash -Algorithm MD5 $exiftool).Hash)
$cmd = "{0} -DateTimeOriginal {1}" -f $exiftool, (Join-Path -Path $PSScriptRoot -ChildPath 'foobar.cr2')
Write-Host ("Invoking '{0}'" -f $cmd)
Invoke-Expression $cmd

Expected Behaviour

When running outside of the debugger (in a standalone PowerShell session, or in the VScode terminal), I get the expected results:

'exiftool' is 'c:\usr\wbin\exiftool.exe' (version 12.2.1.0) {MD5=4ECB5A8B4AA893F3ADFD48E8ACEBC669}
Invoking 'c:\usr\wbin\exiftool.exe -DateTimeOriginal S:\powershell\test\foobar.cr2'
Date/Time Original              : 2019:12:25 16:36:30

Actual Behaviour

When run via the debugger (F5 in VScode) the script hangs:

'exiftool' is 'c:\usr\wbin\exiftool.exe' (version 12.2.1.0) {MD5=4ECB5A8B4AA893F3ADFD48E8ACEBC669}
Invoking 'c:\usr\wbin\exiftool.exe -DateTimeOriginal S:\powershell\test\foobar.cr2'

Here's the version of exiftool.exe on my system:

exiftool.zip

Attached Logs

1614863299-c8495592-f210-48e1-a203-cc687e42687b1614861694455 - Copy.zip

rjmholt commented 3 years ago

This may well be a duplicate of https://github.com/PowerShell/vscode-powershell/issues/2559.

We did some investigation around that issue but weren't able to determine why exiftool.exe specifically interacts badly with the Integrated Console. Unfortunately, we're not likely to be able to prioritise such a specific bug before other issues we're currently working toward.

sba923 commented 3 years ago

Even if not a exact duplicate this does look like it's a very close issue.

I was so convinced this could not be specific to exiftool that I didn't bother searching for that in the existing issues 😜

I do understand that this is very specific and thus low priority.

I'll start looking for workarounds... (all my photo/video related tooling relies on exiftool to extra e.g. the 'date taken' from DSLR RAW images...)

rjmholt commented 3 years ago

Honestly I'm perplexed as to why this occurs with exiftool. I did look into it with the last issue but couldn't see a good reason (it's basically a self-contained Perl script right?).

Anyway, if it's a bad PSReadLine interaction due to the idiosyncrasies of the Integrated Console, it might be something we can mitigate as we rework the integrated console.

sba923 commented 2 years ago

As I had to work on my picture/video management scripts during the holidays, I was hit by this issue once again.

Would there be a way to detect that a script is running under the debugger, so that it could be prevented from running there? This way I would just be reminded that I must run the script outside of VScode?

JustinGrote commented 2 years ago

@sba923 yes, you can $env:TERM_PROGRAM -eq 'vscode'

sba923 commented 2 years ago

$env:TERM_PROGRAM -eq 'vscode'

I confirm this works, so I'm spreading this all around 😥

if ($env:TERM_PROGRAM -eq 'vscode')
{
    Write-Host -ForegroundColor Red ("This script uses 'exiftool'. It will hang if invoked from VScode.")
    Exit(1)
}

Anything I could do to help getting rid of this issue?

SeeminglyScience commented 2 years ago

Can you try just pressing any key when it appears stuck? Make sure the terminal is focused (click somewhere inside it) and just press enter. Please let me know if it continues after that.

sba923 commented 2 years ago

yes it does continue, even after pressing Space or even a!!!

SeeminglyScience commented 2 years ago

Yeah that checks out. I think I know what's up, we'll get it fixed if it is what I think.

SeeminglyScience commented 2 years ago

btw as a workaround this does the job:

'' | exiftool -DateTimeOriginal foobar.cr2

Just piping literally anything is enough.

sba923 commented 2 years ago

btw as a workaround this does the job:

'' | exiftool -DateTimeOriginal foobar.cr2

Just piping literally anything is enough.

Thanks for sharing this workaround.

sba923 commented 2 years ago

Yeah that checks out. I think I know what's up, we'll get it fixed if it is what I think.

Just curious: could you elaborate on what/where the cause is/lies?

SeeminglyScience commented 2 years ago

My guess is that whatever way they check to see if they should expect input is getting triggered by the fact that we have Console.ReadKey pending in a different thread. So they see for whatever reason that something is expecting input, and then it assumes it needs to take input, so it waits until it does?

Purely guess work until we change up how readkey works, but I'm fairly confident.

andyleejordan commented 2 years ago

Hi there, we just released v2022.4.0-preview! Could you please try PowerShell Preview for VS Code and verify this is fixed?

sba923 commented 2 years ago

Hi,

What I get with

$exiftool = (Get-Command exiftool).Path
Write-Host ("'exiftool' is '{0}' (version {1}) {{MD5={2}}}" -f $exiftool, (Get-Item $exiftool).VersionInfo.ProductVersion, (Get-Filehash -Algorithm MD5 $exiftool).Hash)
$exiftool_args = @('-DateTimeOriginal', (Join-Path -Path $PSScriptRoot -ChildPath 'foobar.cr2'))
Write-Host ("Invoking '{0} {1}'" -f $exiftool, ($exiftool_args -join ' '))
& $exiftool @exiftool_args

is:

  1. no more hanging
  2. VScode terminal shows a à upon execution -- seems the readline gets a dummy character from somewhere...

image

andyleejordan commented 2 years ago

Yay! Then this is resolved. I'm aware of the dummy character, there's a race inside PSReadLine that we need to resolve with that project, and so right now we send a dummy character that's just:

        private static readonly ConsoleKeyInfo s_nullKeyInfo = new(
            keyChar: ' ',
            ConsoleKey.DownArrow,
            shift: false,
            alt: false,
            control: false);

Which should be a no-op (but clearly isn't, as you're getting an accented a, and another person is getting a quote).

ghost commented 2 years ago

This issue has been marked as fixed. It has been automatically closed for housekeeping purposes.

sba923 commented 2 years ago

Yay! Then this is resolved. I'm aware of the dummy character, there's a race inside PSReadLine that we need to resolve with that project, and so right now we send a dummy character that's just:

        private static readonly ConsoleKeyInfo s_nullKeyInfo = new(
            keyChar: ' ',
            ConsoleKey.DownArrow,
            shift: false,
            alt: false,
            control: false);

Which should be a no-op (but clearly isn't, as you're getting an accented a, and another person is getting a quote).

Can you please confirm this (the dummy character) is fixed with version 2022.5.0 of the extension and PSReadLine 2.2.5?

andyleejordan commented 2 years ago

Can you please confirm this (the dummy character) is fixed with version 2022.5.0 of the extension and PSReadLine 2.2.5?

Yes indeed it is!

sba923 commented 2 years ago

Can you please confirm this (the dummy character) is fixed with version 2022.5.0 of the extension and PSReadLine 2.2.5?

Yes indeed it is!

Good news! This means I'll no longer need to use the workaround

$result = '' | & $exiftool @exiftool_args

and will be able to use the standard construct instead:

$result = & $exiftool @exiftool_args

Thanks again for the fix. I've been patient 😜.

andyleejordan commented 2 years ago

Very patient. Thank you!