Error handling calling a converted script to exe from a script specifying a wrong named parameter

Ask your PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
xmerlin
Posts: 9
Last visit: Tue May 31, 2022 5:58 am
Has voted: 1 time

Error handling calling a converted script to exe from a script specifying a wrong named parameter

Post by xmerlin »

Failing capture of the error "A parameter cannot be found that matches parameter name ..." in the caller when calling a converted script to exe
It does however work with the same caller script when the called script is NOT converted to an exe

capture error works with calling a script likewise
CODE CALLING SCRIPT
  1. $cmd = "c:\temp\test_param2.ps1"
  2. $ar=@(
  3. "-SearchNonDefaultRootDirs2",
  4. "True",
  5. "-DirectoryNamesOnly2",
  6. "True"
  7. )
  8. try{
  9.   & $cmd @ar -ea Stop
  10. }
  11. catch{
  12.   $errmsg=($_.Exception.Message).replace("`r`n","")
  13.   write-output "ERROR: $errmsg"
  14. }

CODE CALLED SCRIPT
  1. param(
  2.   [parameter(ParameterSetName = "SearchDirectories")]
  3.   [ValidateSet('True', 'False')]
  4.   [string]$WritableWindir='False',
  5.   [parameter(ParameterSetName = "SearchDirectories")]
  6.   [ValidateSet('True', 'False')]
  7.   [string]$DirectoryNamesOnly='False',
  8.   [parameter(ParameterSetName = "SearchDirectories")]
  9.   [ValidateSet('True', 'False')]
  10.   [string]$SearchNonDefaultRootDirs='False'
  11. )
  12.  
  13. write-output "WritableWindir($WritableWindir)"
  14. write-output "DirectoryNamesOnly($DirectoryNamesOnly)"
  15. write-output "SearchNonDefaultRootDirs($SearchNonDefaultRootDirs)"


Output (as expected)

PS C:\temp> ./test_param2.ps1 -DirectoryNamesOnly2 $True
C:\temp\test_param2.ps1 : A parameter cannot be found that matches parameter name 'DirectoryNamesOnly2'.
At line:1 char:19
+ ./test_param2.ps1 -DirectoryNamesOnly2 $True
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [test_param2.ps1], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,test_param2.ps1
[/size]


HOWEVER

The following seems NOT to work correctly?
Same caller script and same called script but this time the called script has been converted to an exe

exe outputs: (in a window when using build setting Windows Application)
Line 1: A parameter cannot be found that matches parameter name 'SearchNonDefaultRootDirs2'.

I tried various build settings for the exe but the error does not get captured in the caller

Is this expected behaviour or not? If it is not, what can be done to capture this error in the caller?
jvierra
Posts: 15221
Last visit: Wed Jun 29, 2022 5:42 pm
Answers: 23
Has voted: 4 times
Been upvoted: 21 times

Re: Error handling calling a converted script to exe from a script specifying a wrong named parameter

Post by jvierra »

You cannot catch an exception in an EXE from a script. THe EXE must handle the exception and set an exit code to pass back to the calling script.

An EXE is not "called" and EXE is executed as another process. Exceptions cannot be passed across process boundaries.
User avatar
xmerlin
Posts: 9
Last visit: Tue May 31, 2022 5:58 am
Has voted: 1 time

Re: Error handling calling a converted script to exe from a script specifying a wrong named parameter

Post by xmerlin »

I recently found this as a possible solution:
build exe setting = command line
using this statement:
$res = cmd /c 'c:\temp\test_param2.exe -SearchNonDefaultRootDirs2 True -DirectoryNamesOnly2 True 2>&1'
Both output and errors now come in variable $res
But the issue with this is now how to distinguish between stdout and stderr as they are merged?
I could prefix regular output with some fixed string to detect the difference but maybe there is a more elegant solution?
User avatar
xmerlin
Posts: 9
Last visit: Tue May 31, 2022 5:58 am
Has voted: 1 time

Re: Error handling calling a converted script to exe from a script specifying a wrong named parameter

Post by xmerlin »

Then I tried the following snippet and strangely enough the error appears on stdout? and exit code = 0
  1. $pinfo = New-Object System.Diagnostics.ProcessStartInfo
  2. $pinfo.FileName = "c:\temp\test_param2.exe"
  3. $pinfo.RedirectStandardError = $true
  4. $pinfo.RedirectStandardOutput = $true
  5. $pinfo.UseShellExecute = $false
  6. $pinfo.Arguments = "-SearchNonDefaultRootDirs2 True -DirectoryNamesOnly2 True"
  7. $p = New-Object System.Diagnostics.Process
  8. $p.StartInfo = $pinfo
  9. $p.Start() | Out-Null
  10. $stdout = $p.StandardOutput.ReadToEnd()
  11. $stderr = $p.StandardError.ReadToEnd()
  12. $p.WaitForExit()
  13. $p.ExitCode
  14. write-host "stdout($stdout)"
  15. write-host "stderr($stderr)"

OUTPUT:

0
stdout(Line 1: A parameter cannot be found that matches parameter name 'SearchNonDefaultRootDirs2'.)
stderr()
jvierra
Posts: 15221
Last visit: Wed Jun 29, 2022 5:42 pm
Answers: 23
Has voted: 4 times
Been upvoted: 21 times

Re: Error handling calling a converted script to exe from a script specifying a wrong named parameter

Post by jvierra »

Exception messages do not appear on StdErr unless you catch them in the script and send them to StdErr. By default all test output is sent to StdOut. Exception messages are sent to the console and when packaged all of that goes to StdOut.

This is the default behavior of all Windows processes and the default behavior of PowerShell. If you want to change that you will have to code it into the script that you want to turn into and EXE.

Also note that the process code you used is very old. "Start-Process" can do that in a simple way and can also be pipelined.
Locked