簡體   English   中英

將變量傳遞給register-objectevent動作塊

[英]pass variable to register-objectevent action block

我實際上試圖每隔50秒運行一次計時器(lmd)。 但是當我按下ctrl + c時,計時器仍然繼續在其動作塊中打印消息。 所以我寫了另一個計時器(ctrlc),每秒運行一次並查找任何按下的ctrlc。 然后取消注冊lmd計時器和ctrl計時器。 並將TreatControlCAsInput重置為false。 但我在ctrlc計時器動作塊中有一個問題。 我無法觸發RemoveTimer功能。 請建議:)

# Disables the timer and unregisters the event subscriber
function RemoveTimer ($timerin, $sourceidentifier) {
     Write-Host "Inside RemoveTimer $sourceidentifier"
    try {
        $timerin.Enabled = $False
        Unregister-Event -SourceIdentifier $sourceidentifier
    } Catch {
    Write-Host "Error occurred while stopping timer $($_.Exception.Message)"
}
}

# Disables the timer and unregisters the event subscriber
function RemoveTimer1 {
    Write-Host "Inside RemoveTimer1"
}

# LMD Timer
try {
    $lmdtimer = New-Object Timers.Timer
    $lmdtimer.Interval = 50000
    $registerevent = Register-ObjectEvent -InputObject $lmdtimer -EventName Elapsed -SourceIdentifier LMDTimer.Output -Action {
        Write-Debug "$($Event | Out-String)"
        Write-Host "Script is running"
    }
    $lmdtimer.Enabled = $True
    Write-Debug "$($lmdtimer | Out-String)"
} Catch {
    Write-Host "Error occurred while starting LMDTimer $($_.Exception.Message)"
    RemoveTimer $lmdtimer "LMDTimer.Output"
}

# CTRLC Timer
try {
    [console]::TreatControlCAsInput = $true
    $ctrlctimer = New-Object Timers.Timer
    $ctrlctimer.Interval = 1000
    $params = new-object psobject -property @{RemoveTimer1 = $function:RemoveTimer1}
    $registerevent = Register-ObjectEvent -InputObject $ctrlctimer -EventName Elapsed -SourceIdentifier CTRLCTimer.Output -MessageData $function:RemoveTimer1 -Action {
        if ($Host.UI.RawUI.KeyAvailable -and (3 -eq [int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
        {
          Write-Host "Removing LMDTimer and CTRLCTimer"
          try {
              #RemoveTimer $lmdtimer "LMDTimer.Output"
              #RemoveTimer $ctrlctimer "CTRLCTimer.Output"
              $Event.MessageData.RemoveTimer1
          } Catch {
              Write-Host $_.Exception.Message
          }
          Write-Host "Removing TreatControlCAsInput"
          [console]::TreatControlCAsInput = $false
          exit
        }
    }
    $ctrlctimer.Enabled = $True
    Write-Debug "$($ctrlctimer | Out-String)"
} Catch {
    Write-Host "Error occurred while starting CTRLCTimer $($_.Exception.Message)"
    RemoveTimer $ctrlctimer "CTRLCTimer.Output"
    [console]::TreatControlCAsInput = $false
}

for ($i=0;$i -lt 4000;$i++) {
    Write-Host "$i"
}

RemoveTimer $lmdtimer "LMDTimer.Output"
RemoveTimer $ctrlctimer "CTRLCTimer.Output"
[console]::TreatControlCAsInput = $false

您可以使用-MessageData參數將信息傳遞給scriptblock:

$pso = new-object psobject -property @{foo = $foo; bar = $bar}
Register-ObjectEvent... -messagedata $pso

之后你應該能夠在Scriptblock中訪問它,如下所示:

$Event.MessageData.foo

我今天也遇到了幾乎相同的問題,請注意函數RemoveTimer1的范圍限制太大,無法在事件的-Action腳本塊中使用。 我能找到的兩個解決方法是:

  1. 調用腳本時,點源腳本
    • PowerShell.exe -File yourScript.ps1
    • . C:\\code\\yourScript.ps1
  2. 將函數添加到全局作用域,然后在完成全局作用后將其刪除function global:RemoveTimer1 { Write-Host "Inside RemoveTimer1" } .... rm function:\\RemoveTimer1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM