Форма PowerShell с веб-браузером, который автоматически обновляется - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь создать простую форму в PowerShell в небольшом окне, которое всегда находится поверх других окон и просто содержит объект веб-браузера, который автоматически обновляется каждые 10 секунд. Я искал в Интернете и пробовал разные варианты, но ничего не помогло. Почти в каждом примере, с которым я сталкиваюсь, обновление формы или веб-браузера происходит при нажатии кнопки, но мне нужно, чтобы веб-браузер автоматически обновлялся без какого-либо вмешательства пользователя. Из того, что я читал, звучит как 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, но я не уверен, как реализовать это в этом примере без какого-либо взаимодействия с пользователем.

Кто-нибудь может понять это?

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Я получил помощь по этому вопросу от пользователя в Reddit , поскольку текущий ответ, приведенный здесь, в частности первая часть ответа, только смутил меня больше.

0 голосов
/ 08 января 2019

Да, вам придется использовать таймер.

См. Пример в этой статье для более подробной информации. Нет, речь не идет о веб-контроле напрямую, но тот же подход может помочь вам.

Сценарий выходного дня: создание праздничного приветствия с помощью PowerShell и WPF

Последний интересный фрагмент кода - как мы можем обновить контент объекта WPF постоянно. Скрипт использует эту возможность для отображения количество дней, часов, минут и секунд до Нового года. Сделать это, мы создаем блок сценария $ countDownUpdate, который содержит Командлет New-Timespan. Это вычисляет разницу между сейчас и полночь 31 декабря 2010 г., затем устанавливает это значение для контента свойство элемента управления меткой.

# 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)"
}

См. Также этот пример:

Часы PowerShell

В итоге я использовал 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"            
    }            
 } ) 
...