You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, finding event metadata is pretty difficult in PS. The event members are deliberately hidden from autocompletion, can't be directly accessed from objects like methods can to reveal metadata which is often useful in determining how you want to work with them, and aren't available for autocompletion.
Additionally, while Register-EngineEvent and Register-ObjectEvent do exist, they won't always work. For example, using some GUI-centric script patterns, many users can run into deadlocks using Register-ObjectEvent and some Forms classes.
To work around this, many scripters resort to using the hidden $obj.add_EventName($handler) methods which are not discoverable, not well-documented (as they are generally considered an implementation detail), and difficult to work with in PS.
Most documentation around events is C#-centric and will recommend the C# syntax for registering and deregistering delegates; obj.EventName += eventHandler;
This creates friction and confusion; users have neither appropriate access to event metadata to determine how to work with them in PS, nor appropriate documentation to fill in the gaps where Register-ObjectEvent isn't a workable solution. Additionally, even discovering event names for use with Register-ObjectEvent is difficult since the members aren't directly available.
Expose event members as actual object members, allowing their names to register for tab completion, and the PSEvent metadata to be shown to users accessing the event.
Implement a custom binder for use with += / -= which bridges the gap by calling the appropriate add_* / remove_* method for the targeted event.
Add some logic into the Compiler to perform a runtime check for LHS being a PSEvent when handling expressions with += or -= operators (this will be dependent on Update readme #1 being implemented, or this check cannot be relied on). If the LHS is PSEvent, call out to the binder from Import issues from VSO #2 and (de)register the event. Naturally, fall back to standard += behaviour if the LHS is not PSEvent.
Demonstration
PS>$ps= [powershell]::Create()
PS>$handler= { Write-Host"event triggered!" }
# Tab completion lists the event member as well
PS>$ps.Invo
InvocationStateInfo Invoke InvokeAsync InvocationStateChanged
PS>$ps.InvocationStateChanged+=$handler
PS>$ps.AddScript('Write-Output "data from pipe"').Invoke()
event triggered!
event triggered!datafrom pipe
PS>$ps.InvocationStateChanged-=$handler
PS>$ps.AddScript('Write-Output "data from pipe"').Invoke()
datafrom pipe
I have working code for this that I can submit as a PR if there is interest in having this be a part of PowerShell. Just have to put some tests together 😎
Below illustrates the metadata event members would show if users attempt to examine them, once the aforementioned changes are in place.
Summary of the new feature/enhancement
Currently, finding event metadata is pretty difficult in PS. The event members are deliberately hidden from autocompletion, can't be directly accessed from objects like methods can to reveal metadata which is often useful in determining how you want to work with them, and aren't available for autocompletion.
Additionally, while
Register-EngineEventandRegister-ObjectEventdo exist, they won't always work. For example, using some GUI-centric script patterns, many users can run into deadlocks usingRegister-ObjectEventand some Forms classes.To work around this, many scripters resort to using the hidden
$obj.add_EventName($handler)methods which are not discoverable, not well-documented (as they are generally considered an implementation detail), and difficult to work with in PS.Most documentation around events is C#-centric and will recommend the C# syntax for registering and deregistering delegates;
obj.EventName += eventHandler;This creates friction and confusion; users have neither appropriate access to event metadata to determine how to work with them in PS, nor appropriate documentation to fill in the gaps where Register-ObjectEvent isn't a workable solution. Additionally, even discovering event names for use with Register-ObjectEvent is difficult since the members aren't directly available.
Proposed technical implementation details (optional)
+=/-=which bridges the gap by calling the appropriateadd_*/remove_*method for the targeted event.+=or-=operators (this will be dependent on Update readme #1 being implemented, or this check cannot be relied on). If the LHS is PSEvent, call out to the binder from Import issues from VSO #2 and (de)register the event. Naturally, fall back to standard+=behaviour if the LHS is notPSEvent.Demonstration
I have working code for this that I can submit as a PR if there is interest in having this be a part of PowerShell. Just have to put some tests together 😎
Below illustrates the metadata event members would show if users attempt to examine them, once the aforementioned changes are in place.