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

Powershell 如何检查System.Windows.Form中的变量更改,powershell,Powershell,我正在显示一个窗体,该窗体在单击按钮后运行另一个脚本。我需要检查脚本完成的状态,以便更新按钮的文本 $ButtonEmailInfo.Add_Click({ $ButtonEmailInfo.Text = "Sending info" $ButtonEmailInfo.Enabled = $false $Form.Refresh() Write-Host("Running start-job") $global:SendClicked = $true

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

$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()方法的等价物

谢谢,
Rich

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

编辑您需要设置一个计时器对象来更新窗口,并允许线程处理Register ObjectEvent的事件输出

$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
}
编辑您需要设置一个计时器对象来更新窗口,并允许线程处理Register ObjectEvent的事件输出。在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() 
})

我不确定脚本是否按预期工作。直到我关闭调用$ButtonEmailInfo.Add_Click()的原始脚本窗口,我才在PS窗口中看到消息“Job completed”(作业已完成)。我似乎记得,如果关闭窗口,它将完成(就像等待访问线程一样)。让我找出一些旧代码,看看我做了什么来绕过它。好的,UI保存了窗口运行的线程。这意味着它不会将其交给后台作业或事件,除非它发生了某些事情,例如在计时器上更新窗口。我已经更新了我的答案以供参考。