powershell 注册事件
一、问题提出
控制台把Ctrl-C
作为取消按键,在C#中以Console.CancelKeyPress
形式出现,有时候我们会想实现在异步循环中按Ctrl-C
退出,并在退出时做一些销毁变量的工作。按CancelKeyPress
类型推断,需要通过绑定委托的形式来实现。
C#中事件使用委托(delegate
)来注册绑定,powershell里委托使用scriptblock
类来编写,那么怎么把写好的脚本块绑定到指定的对象、类之中呢?
二、内容涉及
- 脚本块:ScriptBlock
- 取消事件:Console.CancelKeyPress
- 注册事件:Register-ObjectEvent、Register-EngineEvent
- 参数补全属性:ArgumnetCompleter
三、代码样例
Register-ObjectEvent `
-InputObject ([Console]) `
-EventName "CancelKeyPress"`
-SourceIdentifier "ConsoleCancelEventHandler"`
-Action { Write-Host "Press cancel key: Ctrl-C" }
下面的脚本使用参数补全,指定好-InputObject
的值后按Tab即可快速填充事件名与事件类型
<#
.Synopsis
事件注册模板,以 Ctrl-C 事件为例
#>
[CmdletBinding()]
param (
[Parameter()]
[System.Object]
$InputObject,
[Parameter(Mandatory)]
[ArgumentCompleter( {
[OutputType([System.Management.Automation.CompletionResult])]
param(
[string] $CommandName,
[string] $ParameterName,
[string] $WordToComplete,
[Management.Automation.Language.CommandAst] $CommandAst,
[Collections.IDictionary] $FakeBoundParameters
)
$inputobj = $FakeBoundParameters["InputObject"]
$(
if ($inputobj -is [Type]) { $inputobj.GetEvents() }
else { $InputObject | Get-Member -MemberType Event }
).Name | Where-Object { $_ -like "$WordToComplete*" }
})]
[string]
$EventName,
[Parameter()]
[ArgumentCompleter( {
[OutputType([System.Management.Automation.CompletionResult])]
param(
[string] $CommandName,
[string] $ParameterName,
[string] $WordToComplete,
[Management.Automation.Language.CommandAst] $CommandAst,
[Collections.IDictionary] $FakeBoundParameters
)
$_ = $FakeBoundParameters["InputObject"]
$(
if ($_ -is [Type]) { $_.GetEvents().EventHandlerType }
else { ($_ | Get-Member -MemberType Event).TypeName }
) | Where-Object { $_ -like "$WordToComplete*" }
})]
[string]
$SourceIdentifier,
[Parameter(Mandatory)]
[scriptblock]
$Action
)
Register-ObjectEvent @PSBoundParameters