Powershell 调用消息框、计时器中的函数

Powershell 调用消息框、计时器中的函数,powershell,timer,messagebox,Powershell,Timer,Messagebox,我为我的一个脚本设置了一个计时器,我设置了所有的片段,但似乎无法让计时器在框内调用,它将调用powershell,然后打开框。我想做的是让它倒计时2分钟,然后关闭。下面是我的代码 [void] [System.Reflection.Assembly]::LoadWithPartialName ("System.Drawing") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

我为我的一个脚本设置了一个计时器,我设置了所有的片段,但似乎无法让计时器在框内调用,它将调用powershell,然后打开框。我想做的是让它倒计时2分钟,然后关闭。下面是我的代码

[void] [System.Reflection.Assembly]::LoadWithPartialName ("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

$x = 2*60
$length = $x / 100

Function timer () 
{While($x -gt 0) {
$min = [int](([string]($x/60)).split('.')[0])
$text = " " + $min + " minutes " + ($x % 60) + " seconds left"
Write-Progress "Building Account" -status $text -perc ($x/$length)
start-sleep -s 1
$x--
}
}


$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Timer Example"
$objForm.Size = New-Object System.Drawing.Size(330,380) 
$objForm.StartPosition = "CenterScreen"

$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 = timer

$objForm.Controls.Add($lblLog) 

$objForm.Add_Shown({$objForm.Activate()})

[void] $objForm.ShowDialog()

当前代码创建标签对象,然后在整个倒计时过程中循环,甚至在将其添加到表单之前。PowerShell是单线程的,这意味着您可以运行代码,也可以使用响应表单。如果你想两者兼得,事情很快就会变得非常复杂

作业不是很好的实践,我自己也从来没有在表单中使用过它们,理想情况下,您应该使用另一个运行空间

$x = 100

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Timer Example"
$objForm.Size = New-Object System.Drawing.Size(330,380) 
$objForm.StartPosition = "CenterScreen"

$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 = "Testing"
$objForm.Controls.Add($lblLog)

[PowerShell]$command = [PowerShell]::Create().AddScript({
    Param
    (
        [System.Windows.Forms.Label]$label,
        $x
    )
    While($x -gt 0) {
        $min = [int](([string]($x/60)).split('.')[0])
        $text = " " + $min + " minutes " + ($x % 60) + " seconds left"
        $label.BeginInvoke([System.Action[string]]{
            Param($text)

            $label.Text = $text
        }, $text)
        start-sleep -s 1
        $x--
    }
})
$command.AddParameters(@($lblLog, $x)) | Out-Null

$command.BeginInvoke() | Out-Null
$objForm.ShowDialog()
这样做的目的是创建另一个运行空间,PowerShell可以在其中与主控制台并行运行,并将计时器放在其中。然而表单也是单线程的,所以我们需要调用更新标签的操作(有点像说“嘿,你有空的时候可以这样做吗?”)。我们使用
BeginInvoke
,它只告诉它更新,但不等待,因为您正在运行计时器,必须等待表单可用,这将使您的计数器失效


这对我来说还行,但是表单和标签需要调整大小以适应您的目的。

您当前的代码创建标签对象,然后在整个倒计时过程中循环,甚至在将其添加到表单之前。PowerShell是单线程的,这意味着您可以运行代码,也可以使用响应表单。如果你想两者兼得,事情很快就会变得非常复杂

作业不是很好的实践,我自己也从来没有在表单中使用过它们,理想情况下,您应该使用另一个运行空间

$x = 100

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Timer Example"
$objForm.Size = New-Object System.Drawing.Size(330,380) 
$objForm.StartPosition = "CenterScreen"

$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 = "Testing"
$objForm.Controls.Add($lblLog)

[PowerShell]$command = [PowerShell]::Create().AddScript({
    Param
    (
        [System.Windows.Forms.Label]$label,
        $x
    )
    While($x -gt 0) {
        $min = [int](([string]($x/60)).split('.')[0])
        $text = " " + $min + " minutes " + ($x % 60) + " seconds left"
        $label.BeginInvoke([System.Action[string]]{
            Param($text)

            $label.Text = $text
        }, $text)
        start-sleep -s 1
        $x--
    }
})
$command.AddParameters(@($lblLog, $x)) | Out-Null

$command.BeginInvoke() | Out-Null
$objForm.ShowDialog()
这样做的目的是创建另一个运行空间,PowerShell可以在其中与主控制台并行运行,并将计时器放在其中。然而表单也是单线程的,所以我们需要调用更新标签的操作(有点像说“嘿,你有空的时候可以这样做吗?”)。我们使用
BeginInvoke
,它只告诉它更新,但不等待,因为您正在运行计时器,必须等待表单可用,这将使您的计数器失效


这个测试对我来说还可以,但是表单和标签需要调整大小以满足您的需要。

哦,请注意,大多数流(如输出和错误)不会从单独的运行空间重定向到主控制台(尽管出于某种原因,警告是??)-我不知道进度,但我在测试中没有得到任何结果。$length无论如何都不会通过,因此可能值得将其编辑掉(它实际上会进入Streams属性)。最后,这确实会引发一些错误(也会引发流),因为$command在表单显示之前就开始运行,这意味着它会在标签可用之前尝试更新一次或两次。您可以等待两秒钟,或者使用try/catch,甚至忽略它,仍然可以正常运行。哦,请注意,大多数流(如输出和错误)不会从单独的运行空间重定向到主控制台(尽管出于某种原因,警告是??)-我不知道进度,但我在测试中没有得到任何结果。$length无论如何都不会通过,因此可能值得将其编辑掉(它实际上会进入Streams属性)。最后,这确实会引发一些错误(也会引发流),因为$command在表单显示之前就开始运行,这意味着它会在标签可用之前尝试更新一次或两次。您可以等待两秒钟,或者使用try/catch,甚至忽略它,仍然可以正常运行。