[英]Powershell Timer - Update gui
I have created a powershell timer, and after every 1 second, I would like to run a function to execute or post text to a text box log on the interface. 我创建了一个powershell计时器,每1秒后,我想运行一个函数来执行或将文本发布到界面上的文本框日志。
Run the below. 运行以下。 When you click Start, every 1 second, the log text area should show "Post to log every 1 second, not as a batch".
单击“开始”时,每隔1秒,日志文本区域应显示“每1秒发布一次,而不是批处理”。 However, this messages only appear as a batch, all at once, when you click Stop.
但是,当您单击“停止”时,此消息仅一次性显示为批处理。
This question does not appear to be answered on the internet! 这个问题似乎没有在互联网上得到解答!
Code: 码:
$global:timer = New-Object System.Timers.Timer
$global:timer.Interval = 1000
function AddToLog($logtext)
{
$txtLog.Text = $txtLog.Text + "`r`n" + $logtext
$txtLog.ScrolltoCaret
}
function startTimer() {
Register-ObjectEvent -InputObject $global:timer -EventName Elapsed -SourceIdentifier theTimer -Action {AddToLog('Post to log every 1 second, not as a batch') }
$global:timer.start()
Write-Host "Start Timer"
}
function stopTimer() {
$global:timer.stop()
Write-Host "Close Function"
Unregister-Event theTimer
}
########################
# Setup User Interface
########################
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Timer Example"
$objForm.Size = New-Object System.Drawing.Size(330,380)
$objForm.StartPosition = "CenterScreen"
#Start Button
$btnStart = New-Object System.Windows.Forms.Button
$btnStart.Location = New-Object System.Drawing.Size(10,190)
$btnStart.Size = New-Object System.Drawing.Size(140,35)
$btnStart.Text = "Start"
$btnStart.Add_Click({StartTimer; })
$objForm.Controls.Add($btnStart)
#Stop Button
$btnStop = New-Object System.Windows.Forms.Button
$btnStop.Location = New-Object System.Drawing.Size(150,190)
$btnStop.Size = New-Object System.Drawing.Size(140,35)
$btnStop.Text = "Stop"
$btnStop.Add_Click({StopTimer; })
$objForm.Controls.Add($btnStop)
$btnStop.Enabled = $true
#Log Area
$lblLog = New-Object System.Windows.Forms.Label
$lblLog.Location = New-Object System.Drawing.Size(10,230)
$lblLog.Size = New-Object System.Drawing.Size(80,20)
$lblLog.Text = "Event Log:"
$objForm.Controls.Add($lblLog)
$txtLog = New-Object System.Windows.Forms.Textbox
$txtLog.Location = New-Object System.Drawing.Size(10,250)
$txtLog.Size = New-Object System.Drawing.Size(290,90)
$txtLog.Multiline = $True
$txtLog.Scrollbars = "vertical"
$txtLog.Add_Click({$txtLog.SelectAll(); $txtLog.Copy()})
$objForm.Controls.Add($txtLog)
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
Thanks for your help in advanced. 感谢您的高级帮助。
-R -R
Try using a System.Windows.Forms.Timer
. 尝试使用
System.Windows.Forms.Timer
。 See this article for info on the differences between .NET timers . 有关.NET计时器之间差异的信息,请参阅此文章 。
In the case of a WinForms timer, ditch the Register-ObjectEvent and Unregister-Event and add this line before you call ShowDialog(): 对于WinForms计时器,抛弃Register-ObjectEvent和Unregister-Event并在调用ShowDialog()之前添加此行:
$timer.add_Tick({AddToLog('Post to log every 1 second, not as a batch')})
Don't forget to change to System.Windows.Forms.Timer. 不要忘记更改为System.Windows.Forms.Timer。 When I make those change, the UI works.
当我进行这些更改时,UI会起作用。
Use of Register-ObjectEvent requires that PowerShell services the event queue at various safe points in its execution. 使用Register-ObjectEvent要求PowerShell在其执行的各个安全点为事件队列提供服务。 However, since PowerShell is blocked inside some .NET code (Form.ShowDialog()), it doesn't get a chance to service its event queue.
但是,由于PowerShell在某些.NET代码(Form.ShowDialog())中被阻止,因此它无法为其事件队列提供服务。
I took what you had, and looked at this egg_timer project and came up with the following: 我拿走了你所拥有的东西,看了看这个egg_timer项目并提出了以下建议:
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.add_tick({AddToLog 'Post to log every 1 second, not as a batch'})
function AddToLog($logtext)
{
$txtLog.Text = $txtLog.Text + "`r`n" + $logtext
$txtLog.ScrolltoCaret
}
function startTimer() {
$timer.start()
}
function stopTimer() {
$timer.Enabled = $false
Write-Host "Close Function"
}
########################
# Setup User Interface
########################
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Timer Example"
$objForm.Size = New-Object System.Drawing.Size(330,380)
$objForm.StartPosition = "CenterScreen"
#Start Button
$btnStart = New-Object System.Windows.Forms.Button
$btnStart.Location = New-Object System.Drawing.Size(10,190)
$btnStart.Size = New-Object System.Drawing.Size(140,35)
$btnStart.Text = "Start"
$btnStart.Add_Click({StartTimer; })
$objForm.Controls.Add($btnStart)
#Stop Button
$btnStop = New-Object System.Windows.Forms.Button
$btnStop.Location = New-Object System.Drawing.Size(150,190)
$btnStop.Size = New-Object System.Drawing.Size(140,35)
$btnStop.Text = "Stop"
$btnStop.Add_Click({StopTimer; })
$objForm.Controls.Add($btnStop)
$btnStop.Enabled = $true
#Log Area
$lblLog = New-Object System.Windows.Forms.Label
$lblLog.Location = New-Object System.Drawing.Size(10,230)
$lblLog.Size = New-Object System.Drawing.Size(80,20)
$lblLog.Text = "Event Log:"
$objForm.Controls.Add($lblLog)
$txtLog = New-Object System.Windows.Forms.Textbox
$txtLog.Location = New-Object System.Drawing.Size(10,250)
$txtLog.Size = New-Object System.Drawing.Size(290,90)
$txtLog.Multiline = $True
$txtLog.Scrollbars = "vertical"
$txtLog.Add_Click({$txtLog.SelectAll(); $txtLog.Copy()})
$objForm.Controls.Add($txtLog)
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.