为什么我的WindowsForm在执行循环时没有响应

时间:2016-02-08 10:52:30

标签: winforms powershell

这可能是一个难以回答的问题。我写了一个脚本来检查进程的响应属性。为了可视化脚本正在运行,我创建了一个窗口表单,您可以在其中查看正在监视的进程。该脚本运行完美,但我无法对我的winform做任何事情。无法最小化或关闭它,只要我将光标移动到windowsform,我的鼠标光标就会切换到沙漏符号。任何想法为什么?

当我注释掉while循环时,winform也没有响应

这是我的代码:

if ($ShowWindowsForm){
    $window = New-Object System.Windows.Forms.Form
    $window.text = "Process Watcher"
    $window.size = New-Object System.Drawing.Size(350,100) 
    $window.location = New-Object System.Drawing.Size(100,100) 
    $icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell.exe")
    $window.Icon = $Icon
    $text = New-Object System.Windows.Forms.Label
    $text.Text = "Folgender Prozess wird überwacht:`n$target.exe"
    $text.location = New-Object System.Drawing.Size(10,10) 
    $text.AutoSize = $true
    $window.Controls.Add($text)
    $window.Show()
}
while (1) {
    sleep -Milliseconds 100
    if(!((get-process $target).Responding -eq $true)) {
    #do stuff
}

1 个答案:

答案 0 :(得分:2)

我现在得到了答案,如果有人遇到与我相同的问题。

首先,如果你只是创建一个GUI并进行一些处理,他们会使用相同的线程。例如:

# Windows Form    
$window = New-Object System.Windows.Forms.Form
$window.text = "Process Watcher"
$window.size = New-Object System.Drawing.Size(350,100) 
$window.location = New-Object System.Drawing.Size(100,100) 
$window.ShowDialog()

# Processing
while (1) { # Do Stuff }

由于$window方法,PowerShell现在会显示.ShowDialog(),但Windows窗体($window)将无法响应。那是因为你在显示Windows窗体对话框的同一个线程中运行一个循环。

因此我们需要为循环创建一个后台任务,因此它有一个自己的线程。这就是PowerShell的Start-Job cmdlet的用途。

假设您正在监控某个流程,并希望在Windows窗体中对其进行可视化。您的代码将如下所示:

$target = "firefox"

# Job
Start-Job -argumentlist $target {
    param($target)
    while ((get-process $target).Responding) {Sleep -Milliseconds 100}
    if (!(get-process $target).Responding) {<# Do Stuff #>}
}

# Windows Form    
$window = New-Object System.Windows.Forms.Form
$window.text = "Process Watcher"
$window.size = New-Object System.Drawing.Size(350,100) 
$window.location = New-Object System.Drawing.Size(100,100) 
$window.ShowDialog()

使用此代码,您的Windows窗体负责,并且您的循环在后台执行。我还希望通过此代码示例显示,您必须将使用-argumentlist参数和param()语句将在作业scriptblock外声明的变量传递给作业。否则它将无法工作。

我希望这个答案会对某人有所帮助,因为谷歌并没有真正给出一个好的答案(或者我找不到好的答案)