带有自动刷新的 Web 浏览器的 PowerShell 表单

PowerShell Form with Web Browser that Automatically Refreshes

我正在尝试在 PowerShell 中创建一个小型 window 的简单表单,该表单始终位于其他 windows 之上,并且仅包含一个每 10 秒自动刷新一次的 Web 浏览器对象。我一直在网上搜索并尝试各种选择,但似乎没有任何效果。几乎我遇到的每个示例都在按下按钮时刷新表单或 Web 浏览器,但我需要 Web 浏览器在没有任何用户交互的情况下自行自动刷新。从我一直在阅读的内容来看,WPF(Windows Presentation Foundation)和 XAML(可扩展应用程序标记语言)听起来像是要走的路,因为 WinForms 被限制在单个线程中,这让人耳目一新表格更难或不可能有效地完成。

现在这是我没有自动刷新的情况(使用 google 测试):

[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="PowerShell HTML GUI" WindowStartupLocation="Manual">
    <Grid>
        <WebBrowser
            HorizontalAlignment="Left"
            Width="415"
            Height="340"
            Margin="10,10,0,0"
            VerticalAlignment="Top"
            Name="WebBrowser"
        />
    </Grid>
</Window>
'@
$reader = New-Object System.Xml.XmlNodeReader($xaml)
$Form = [Windows.Markup.XamlReader]::Load($reader)
$Form.Width = 415
$Form.Height = 340
$Form.Topmost = $True
$WebBrowser = $Form.FindName('WebBrowser')
$WebBrowser.add_Loaded({$this.Navigate('http://www.google.com')})
$Form.ShowDialog()

我尝试在代码末尾添加以下循环来替换 $Form.ShowDialog(),但显然这是行不通的。

While (1) {
    Start-Sleep -seconds 10
    $WebBrowser.Refresh()
    $Form.ShowDialog()
}

我想我需要使用 System.Windows.Forms.Timer class,但我不确定如何在没有任何用户交互的情况下将其实现到这个示例中。

有人能解决这个问题吗?

是的,您将不得不使用计时器。

有关详细信息,请参阅本文中的示例。不,它不是直接与 Web 控件对话,但同样的方法可以让您到达那里。

Weekend Scripter: Create a Holiday Greeting Using PowerShell and WPF

The final interesting piece of code is how we can update the content of a WPF object continually. The script uses this ability to display the number of days, hours, minutes & seconds until the New Year. To do this, we create a $countDownUpdate scriptblock that contains a New-Timespan cmdlet. This calculates the difference between now and midnight on 31st December 2010, then sets this value on the content property of a label control.

# scriptblock that gets called every second by the timer object
# updates the 'content' property of the countdownlabel
$countDownUpdate = {
    $ts = New-TimeSpan -Start $([datetime]::now) -End $([datetime]"12/31/2010 00:00:00")

    # find the countdown label control
    $lbl = $objCanvas.FindName("countDown")
    $lbl.content = "$($ts.Days) . $($ts.Hours) : $($ts.Minutes) : $($ts.Seconds)"
}

另见这个例子:

A PowerShell clock

I ended up using Windows Presentation Foundation

## Create a script block which will update the UI            
 $counter = 0;            
 $updateBlock = {            
    # Update the clock            
    $clock.Resources["Time"] = [DateTime]::Now.ToString("T")            
 }            

## Hook up some event handlers             
$clock.Add_SourceInitialized( {            
    ## Before the window's even displayed ...            
    ## We'll create a timer            
    $timer = new-object System.Windows.Threading.DispatcherTimer            
    ## Which will fire 4 times every second            
    $timer.Interval = [TimeSpan]"0:0:0.25"            
    ## And will invoke the $updateBlock            
    $timer.Add_Tick( $updateBlock )            
    ## Now start the timer running            
    $timer.Start()            
    if( $timer.IsEnabled ) {            
       Write-Host "Clock is running. Don't forget: RIGHT-CLICK to close it."            
    } else {            
       $clock.Close()            
       Write-Error "Timer didn't start"            
    }            
 } ) 

我从 Reddit 的一位用户那里得到了帮助,因为这里提供的当前答案,特别是答案的第一部分,只会让我更加困惑。