如何检查System.Windows.Form中的变量更改

时间:2014-08-14 13:46:55

标签: powershell

我正在显示一个单击按钮后运行另一个脚本的表单。我需要检查脚本完成的状态,以便我可以更新按钮的文本。

$ButtonEmailInfo.Add_Click({
    $ButtonEmailInfo.Text = "Sending info"
    $ButtonEmailInfo.Enabled = $false
    $Form.Refresh()
    Write-Host("Running start-job")
    $global:SendClicked = $true
    $global:SJob = Start-Job -filepath ($path + "\Send-Info.ps1")
    $ButtonEmailInfo.Text = "Info sent"
    $Form.Refresh()
})

上述代码的问题在于,在调用脚本Send-Info.ps1完成之前,按钮文本被设置为“Info sent”。

我可以测试$ global:SJob.Finished也看看脚本是否已经完成,但我不确定你是如何在表单中执行此操作的。是否有相应的update()方法定期检查?

谢谢, 富

1 个答案:

答案 0 :(得分:1)

您可以使用Register-ObjectEvent来处理作业并在完成后执行操作。您可以在开始工作后立即添加以下内容。

编辑您需要设置一个Timer对象来更新Window并允许线程处理Register-ObjectEvent的Event输出。

$global:SJob = Start-Job -filepath ($path + "\Send-Info.ps1")
Register-ObjectEvent -InputObject $Global:SJob -EventName StateChanged -SourceIdentifier JobWatcher -Action {
    #Job completed actions go here
    Write-Host "Job Completed!"
    # $Event.Sender is the actual job object that you can either remove or retrieve data from
    #Perform cleanup of event subscriber
    Unregister-Event -SourceIdentifier $Event.SourceIdentifier
    Remove-Job -Name $Event.SourceIdentifier -Force
}

这是一个示例,您可以运行以查看它的运行情况,而不会在完成时通知表单,然后继续删除作业和事件订阅。

$SJob = Start-Job {start-sleep -seconds 10} -Name TESTJOB
Register-ObjectEvent -InputObject $SJob -EventName StateChanged -SourceIdentifier JobWatcher -Action {
    #Job completed actions go here
    Write-Host "Job $($Event.Sender.Name) Completed!"
    #Remove job
    Remove-Job $Event.Sender
    #Perform cleanup of event subscriber and its job
    Unregister-Event -SourceIdentifier $Event.SourceIdentifier
    Remove-Job -Name $Event.SourceIdentifier -Force
}

编辑您需要设置一个Timer对象来更新Window并允许线程处理Register-ObjectEvent的Event输出。将以下行添加到UI以在窗口加载时创建计时器,并在计时器关闭时停止计时器。

$Window.Add_Loaded({
    ##Configure a timer to refresh window##
    #Create Timer object
    $Script:timer = new-object System.Windows.Threading.DispatcherTimer 
    #Fire off every 5 seconds
    $timer.Interval = [TimeSpan]"0:0:1.00"
    #Add event per tick
    $timer.Add_Tick({
        [Windows.Input.InputEventHandler]{ $Script:Window.UpdateLayout() }
    })
    #Start timer
    $timer.Start()
    If (-NOT $timer.IsEnabled) {
        $Window.Close()
    }

}) 

$Window.Add_Closed({
    $Script:timer.Stop() 
})