3

I'm following Microsoft examples and I get an error when I run this in PowerShell (5.1). I am unable to repro this in the ISE.

$app="notepad2354.exe"
try{
   iex $app
}
catch [System.Management.Automation.CommandNotFoundException]{
   write-host 'ERROR! The app file could not be found.'
}
catch {
   write-host 'ERROR! Unknown error when executing the step. Error: ' + $_.Exception.Message
}

Error:

catch : The term 'catch' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

The odd thing is it works fine on the first catch. If I switch the order, the second one always fails with this message. Any ideas why this is error'ing?

UnhandledExcepSean
  • 12,504
  • 2
  • 35
  • 51
  • That syntax seems to work, according to [this thread](https://stackoverflow.com/questions/6779186/powershell-try-catch-finally). I'm not able to reproduce on Powershell v4. What Powershell version are you on? – Rich Moss May 29 '19 at 19:05
  • my setup = win7, ps5.1 ///// i DO NOT get that error when the general catch is 1st - i get `Catch block must be the last catch block.` - which is what one would expect since the generic catch is for "none of the previous ones matched". ///// i suspect you have a typo OR an invalid character in there that is making PoSh think the `catch` is not matching up with a previous `try`. – Lee_Dailey May 29 '19 at 19:23
  • @Lee_Dailey I literally copied the text from my question and I get an error on the second catch – UnhandledExcepSean May 29 '19 at 19:27
  • what version of PoSh are you running? – Lee_Dailey May 29 '19 at 19:28
  • @Lee_Dailey 5.1.14393.2879 – UnhandledExcepSean May 29 '19 at 19:29
  • 1
    i am lost. [*sigh ...*] your code - copy-pasted into my ISE window - runs correctly. when i reverse the two `catch` blocks, the error i get is `Catch block must be the last catch block.` - as expected. – Lee_Dailey May 29 '19 at 19:35
  • 1
    @Lee_Dailey Figured out the problem. It was mostly user error. This is the first thing I haven't been able to simply paste into a PowerShell window and run. – UnhandledExcepSean May 29 '19 at 19:36
  • 1
    @UnhandledExcepSean - thanks for posting the fix ... i still don't understand the WHY of it ... but you got it working and that is the prime concern. [*grin*] – Lee_Dailey May 29 '19 at 19:50
  • 1
    @Lee_Dailey I figured it out, it is because of `PSReadline`. See my Answer post below. – HAL9256 May 29 '19 at 20:40
  • 1
    @UnhandledExcepSean - oh. my. goodness ... thank you for calling that to my attention! [*grin*] – Lee_Dailey May 29 '19 at 20:45

3 Answers3

3

To add to @UnhandledExcepSean answer where he saw that his issue is with Copy\Pasting into PowerShell console.

The root issue is that PSReadline changed the right-click pasting functionality.

PSReadline, originally offered as an installable module for PowerShell v3 and v4, now comes default with PowerShell v5+ and PowerShell Core 6+. It is a nice module that adds a bunch of new things like syntax highlighting, better multi-line editing experience, etc.

When PSReadline is imported, Right-Click pasting doesn't "work" as expected see GitHub issue: Right click paste should work mostly like Ctrl+v paste 579. What happens is in:

PSReadLine, if the input is "complete", as in, it parses without an IncompleteParseException, then the input will be accepted...

[https://github.com/PowerShell/PSReadLine/issues/579#issuecomment-345824783]

Basically, the Right-Click pasting comes from the Windows PowerShell terminal "GUI" host, and streams in the characters into the PowerShell console, where they are being intercepted and interpreted by PSReadline to provide things like syntax highlighting. As it streams in, the trailing } curly brace + newline, completes the statement, and it executes. The second catch statement on the new line then errors out because it is, indeed, on it's own not correct.

Instead, if you use Ctrl+V to paste, the above Copy/Pasting of code does work. the Ctrl+V functionality delivers the entire clipboard contents at once to PSReadline, which interprets everything as a whole before continuing with the execution.

You don't see this happen PowerShell ISE or scripts because Right-Click Pasting doesn't happen.

For fun, you can remove PSReadline in your PowerShell console session:

Remove-Module PSReadline

And then see that Right-Click paste now works as "expected".... Although all the goodness of PSReadline are also gone :-(

Since the Right-Click functionality is specifically a Windows PowerShell terminal issue, even if PSReadline wanted to intercept the Right-Click mouse-hook, it would require PSReadline to now use Windows specific API's to emulate the Windows clipboard feature. This go against "Core" cross-platform functionality. This means that this Right-Click anomaly will likely persist with Ctrl+V to paste as the only recommended way to paste.

HAL9256
  • 12,384
  • 1
  • 34
  • 46
1

Your type-specific catches should always come before your catch-all, so expect an error if you switch the order of the catches above. However, the error you're getting is not what I'd expect, so I can only assume you've got a syntax typo somewhere. The only way I can repro this is if I execute a catch block without a try in front of it.

Matt McNabb
  • 362
  • 4
  • 15
1

So, it turns out that I can't simply copy and paste that script into a PowerShell command window. It works in the ISE and, as I just found out, it works inside a Powershell Script file.

My guess is that it processes the try..catch as a batch and doesn't read the entire pasted command before executing. You can work around this issue by making sure the second catch is on the same line as the first catch ends, like so:

$app="notepad2354.exe"
try{
   iex $app
}
catch [System.Management.Automation.CommandNotFoundException]{
   write-host 'ERROR! The app file could not be found.'
} catch {
   write-host 'ERROR! Unknown error when executing the step. Error: ' + $_.Exception.Message
}
UnhandledExcepSean
  • 12,504
  • 2
  • 35
  • 51