Home > other >  PowerShell Forms. How come in my Form Closing event If I can't call a Function or use Write-out
PowerShell Forms. How come in my Form Closing event If I can't call a Function or use Write-out

Time:12-07

I have a small form I'm working on but I have something I'm confused about. I have a closing event $Form.Add_Closing({}) In there I'm wanting to stop a custom logging module but it doesn't reflect the output to the console, same if I use write-output. If I use Write-Host though, that reflects to the console. Does the Closing event just have any real output capability?

$Form.Add_Closing({
# my logging function - doesn't work
Write-Log -Stop

# Write-Output - doesn't work
Write-Output 'Test message'

# Write-Host - does work
Write-Host 'Another Test message'
})

CodePudding user response:

The problem applies to all events, not just Closing:

Inside a PowerShell script block serving as a .NET event delegate:

  • You can call arbitrary commands...

  • ... but their success-stream (pipeline) output is discarded.

However, output to any of PowerShell's other output streams does surface in the caller's console, as you've experienced with Write-Host.

Therefore, if you simply want to print the called commands' success output to the caller's display, you can pipe them to Out-Host:

$Form.Add_Closing({
  Write-Log -Stop | Out-Host
})

Note:

  • Out-Host's output - unlike Write-Host's - can fundamentally neither be captured nor suppressed.

  • Output from Write-Host, which since v5 writes via the information stream, can be suppressed with 6>$null, and in principle be captured via the common -InformationVariable parameter, if your script is an advanced script and it is invoked with, say, ./yourScript -InformationVariable capturedInfoStream.
    However, this does not work with Write-Host calls made inside event-delegate script blocks.


If you want to collect success output emitted from event-delegate script blocks for later use in the script (which also allows you to control if the collected output is sent to the script's caller or not), create a list in the script scope, to which you can append from the event-delegate script blocks:

# Initialize a list to collect event-delegate output in.
$outputFromEventDelegates = [Collections.Generic.List[object]] @()

# ...

$Form.Add_Closing({
  # Call the function of interest and add its output to the
  # script-scope list.
  $outputFromEventDelegates.AddRange(
    @(Write-Log -Stop)
  )
})

# ... after the .ShowDialog() call

# Now you can access all collected output.
Write-Verbose -Verbose "Output collected from event delegates:"
$outputFromEventDelegates
  • Related