Skip to main content
deleted 49 characters in body
Source Link
mclayton
  • 10.4k
  • 3
  • 26
  • 36

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...

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...

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, 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...

added 866 characters in body
Source Link
mclayton
  • 10.4k
  • 3
  • 26
  • 36

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 scriptblokscriptblock 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...

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 scriptblok 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.

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...

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...

Source Link
mclayton
  • 10.4k
  • 3
  • 26
  • 36

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 scriptblok 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.

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...