Создание и обновление панели состояния

#.net #powershell #paint #statusbar

#.net #powershell #Краски #строка состояния

Вопрос:

Я пытаюсь создать графический интерфейс в powershell, используя некоторые .net, и, учитывая мой небольшой опыт написания программ на основе графического интерфейса, у меня возникают проблемы с обновлением метки.

Я просто создаю простую форму с меткой, и я хочу, чтобы метка заменялась каждый раз при чтении имени папки. Идея состоит в том, чтобы имитировать окно состояния для программы, для запуска которой требуется некоторое время, и обновлять панель с информацией о ходе выполнения программы.

Вот мой код:

 $form = New-Object System.Windows.Forms.Form
$form.Height = 350
$form.Width = 600

$label = New-Object System.Windows.Forms.Label
$label.Text = "first label"
$form.Controls.Add($label)
$form.showDialog()

$dir = ls C: -Directory
[int]$i = 0

while($i -lt $dir.Count) {

   $label.Text = $dir[$i].Name
   $form.Controls.Add($label)
   $form.paint
   sleep 3 # Added this just to make sure I'm not missing the display
   $i  
}
 

Я предполагаю, что должен быть вызов paint, но я не уверен, как это обновит графический интерфейс.

Ответ №1:

Вот ответ на ваш вопрос. Я заменяю $form.ShowDialog() на $form.Show() . Я также добавляю $form.Close() в конце, но результат для меня не так хорош; посмотрите в конце, чтобы найти более эффективное решение для PowerShell.

 [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object System.Windows.Forms.Form
$form.Height = 350
$form.Width = 600

$label = New-Object System.Windows.Forms.Label
$label.Text = "first label"
$form.Controls.Add($label)
$form.Show()

$dir = ls C: -Directory
[int]$i = 0

while($i -lt $dir.Count) {

   $label.Text = $dir[$i].Name
   $form.Controls.Add($label)
   #$form.paint
   sleep 1 # Added this just to make sure I'm not missing the display
   $i  
}

$form.Close()
 

Совет по кодированию: Рассмотрите возможность использования цикла foreach, несмотря на цикл while здесь foreach ($file in $dir) . Здесь нет необходимости вводить $i как int . В сценариях старайтесь использовать полное имя командлета (Get-ChilItem), а не псевдонимы (ls, dir …), Даже если это обычные псевдонимы, это более читабельно. Не расстраивайтесь, вы можете забыть об этом; o)

Теперь мой совет о том, как вы решите решить свою проблему. PowerShell предоставляет некоторые материалы для отображения прогресса. Вот небольшой пример :

 $dirs = Get-ChildItem C: -Directory
$i = 0
foreach($dir in $dirs)
{
   Write-Progress -Activity "looking for Directories" -status "Found $($dir.fullname)" -percentComplete ($i*100 / $dirs.count)
   sleep 1 # Added this just to make sure I'm not missing the display
   $i  
}
 

Комментарии:

1. Есть ли какой-либо способ записать область выполнения внутри графического интерфейса?

2. Да, если вы запустите мой образец с помощью PowerShell ISE, он будет отображаться как графический

3. Другим решением является использование WindowsForm или WPF и использование правильного графического объекта. Таким образом, вы должны использовать задание и способ объединения или написать свой собственный объект .net.

4. Да, JP, это работает, но это отдельно от моей формы. Я пытаюсь добавить его в свою форму, чтобы он работал как единое целое (если это имеет смысл).

5. Да, я использовал start-job так, как вы описали! Кроме того, большое спасибо за другие предложения, которые вы предоставили. Все они очень полезны.