2013-11-27 76 views
2

我已經創建了一個powershell定時器,並且在每隔1秒後,我想運行一個函數來執行或將文本發佈到界面上的文本框日誌。Powershell定時器 - 更新gui

運行以下。當您單擊「開始」時,每隔1秒鐘,日誌文本區域應顯示「每隔1秒記錄一次,而不是批量記錄」。但是,當您單擊「停止」時,此消息只會一次顯示爲批處理。

這個問題似乎沒有在網上回答!

代碼:

$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() 

感謝先進的幫助。

-R

+0

我複製粘貼代碼,當我點擊停止沒有得到在GUI中的任何消息。你能重新檢查你的代碼嗎? – Vish

+0

@Vish我把它粘貼到一個腳本文件的代碼,然後運行腳本?嘗試將代碼粘貼到控制檯窗口中,然後按照Rya描述的那樣工作。 –

回答

1

我把你所得到的,看着這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() 
2

嘗試使用System.Windows.Forms.Timer。請參閱this article for info on the differences between .NET timers

在一個WinForms定時器的情況下,溝註冊-ObjectEvent和註銷,事件和調用的ShowDialog(前加入這一行):

$timer.add_Tick({AddToLog('Post to log every 1 second, not as a batch')}) 

不要忘記更改爲System.Windows。 Forms.Timer。當我做出這些更改時,UI將起作用。

使用Register-ObjectEvent要求PowerShell在其執行的各個安全點處服務事件隊列。但是,由於PowerShell在某些.NET代碼(Form.ShowDialog())中被阻塞,因此無法爲其事件隊列提供服務。

+0

嗨基思,雖然System.Windows.Forms.Timer可能工作,但我似乎無法找到System.Windows.Forms.Timer寫入主機的基本示例,可以說每2秒「仍在運行」,直到過程說停止運行。或甚至在界面上登錄,就像我的例子... – Rya

+0

看到我更新的答案。 –

+0

謝謝;這工作對我來說,而我發現所有其他答案阻塞線程,如你所說。 – Josh