This answer doesn't address your question, but it does fix your problem :-)...
Inside your create_taskbar_menu2 function, change:
$MenuItem2.add_Click({menu4clickEvent $trayIcon})
to
$MenuItem2.add_Click({
menu4clickEvent $trayIcon
}.GetNewClosure()
)
I think what's happening is that the callback ScriptBlock - i.e. { menu4clickEvent $trayIcon } - is being executed in a separate scope to your function, and there's no variable called $trayIcon in scope when the ScriptBlock gets executed.
The call to GetNewClosure() creates a new scriptblock and "binds" (for want of a better word - not sure of the exact terminology) the current value of the function's $trayIcon parameter to the $trayIcon variable inside the ScriptBlock's scope to the same value it has in the function's scope, so now when your callback gets executed, $trayIcon has the value you'd expect it to have.
To see a smaller example of this in action, compare these two scripts:
Set-StrictMode -Version "Latest";
function Get-MyCallback1
{
param( $x )
return { write-host $x }
}
$callback = Get-MyCallback1 "aaa"
$callback.Invoke()
which fails with:
Exception calling "Invoke" with "0" argument(s): "The variable '$x' cannot be retrieved because it has not been set."
At line:1 char:1
+ $callback.Invoke()
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : RuntimeException
versus
Set-StrictMode -Version "Latest";
function Get-MyCallback2
{
param( $x )
return { write-host $x }.GetNewClosure()
}
$callback = Get-MyCallback2 "aaa"
$callback.Invoke()
which outputs:
aaa
As for debugging PowerShell, I've never tried it, but may try what @Lex Li suggested - attach a debugger (e.g. using Visual Studio -> Debug -> Attach to Process...) to the running instance of powershell.exe and see if it triggers debugging when your exception happens...