这可能是一个难以回答的问题。我写了一个脚本来检查进程的响应属性。为了可视化脚本正在运行,我创建了一个窗口表单,您可以在其中查看正在监视的进程。该脚本运行完美,但我无法对我的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
}
答案 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外声明的变量传递给作业。否则它将无法工作。
我希望这个答案会对某人有所帮助,因为谷歌并没有真正给出一个好的答案(或者我找不到好的答案)