#.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 так, как вы описали! Кроме того, большое спасибо за другие предложения, которые вы предоставили. Все они очень полезны.