Powershell show windows form

Создаем простой графический интерфейс GUI для скрипта PowerShell

Одним из существенных недостатков скриптов PowerShell при использовании их простыми пользователями (не сисадминами или программистами) — его консольный интерфейс. Результат выполнения скрипта PoSh отображается также в командной строке и не всегда удобен для восприятия конечного пользователя. Однако Powershell это мощное и современное средство автоматизации для Windows, которое позволяет прозрачно использовать разнообразные объекты .NET Framework. К примеру, с помощью API. NET вы сможете легко создать простой графический интерфейс для ваших PowerShell скриптов.

В этом примере вы покажем, как с помощью PowerShell создать простую Windows форму и расположить на ней различные стандартные диалоговые элементы (кнопки, поля для ввода, текстовые элементы, выпадающие списки). К примеру наша задача – написание простого GUI для определения времени последней смены пароля пользователя в Active Directory. Логика скрипта следующая — из AD в выпадающий список загружается список всех учетных записей в домене. Пользователь выбирает учетную запись, нажимает кнопку и в текстовом поле отображается данные о последнем времени смены пароля пользователя.

В данном примере мы используем PowerShell 3.0+ (я буду писать скрипт в PowerShell ISE в Windows 10).

Для использования функционала .NET по созданию форм мы воспользуемся классом System.Windows.Forms. Загрузить данный класс в сессию PowerShell можно так:

Add-Type -assembly System.Windows.Forms

Теперь создадим графическую форму (окно):

$window_form = New-Object System.Windows.Forms.Form

Установим заголовок и размеры окна формы (в пикселях):

$window_form.Text =’Пример графического интерфейса для скрипта PowerShell’
$window_form.Width = 500
$window_form.Height = 200

Чтобы форма автоматически растягивалась, если элементы расположенные на форме выйдут за границы, нужно включить атрибут AutoSize:

Теперь можно отобразить форму на экране.

Как вы видите, на экране появилась пустая форма указанных размеров. Чтобы добавить не нее различные графические диалоговые элементы, перед строкой $window_form.ShowDialog() добавим следующие строки.

Создадим на форме надпись:

$FormLabel1 = New-Object System.Windows.Forms.Label
$FormLabel1.Text = «Выберите пользователя домена AD»
$FormLabel1.Location = New-Object System.Drawing.Point(0,10)
$FormLabel1.AutoSize = $true
$window_form.Controls.Add($FormLabel1)

Создадим выпадающий список и заполним его списком учетных записей из домена, полученных с помощью командлета Get-ADuser (входит в модуль ActiveDirectory для PowerShell).

$FormComboBox = New-Object System.Windows.Forms.ComboBox
$FormComboBox.Width = 250
$Users = get-aduser -filter * -Properties SamAccountName
Foreach ($User in $Users)
<
$FormComboBox.Items.Add($User.SamAccountName);
>
$FormComboBox.Location = New-Object System.Drawing.Point(60,10)
$window_form.Controls.Add($FormComboBox)

Отобразим еще две надписи. Во второй будет отображаться время последней смены пароля выбранного пользователя.

$FormLabel2 = New-Object System.Windows.Forms.Label
$FormLabel2.Text = «Последняя смена пароля:»
$FormLabel2.Location = New-Object System.Drawing.Point(0,40)
$FormLabel2.AutoSize = $true
$window_form.Controls.Add($FormLabel2)
$FormLabel3 = New-Object System.Windows.Forms.Label
$FormLabel3.Text = «»
$FormLabel3.Location = New-Object System.Drawing.Point(140,60)
$FormLabel3.AutoSize = $true
$window_form.Controls.Add($FormLabel3)

Теперь поместим на форму кнопку действия с надписью «Проверить»:

$FormButton = New-Object System.Windows.Forms.Button
$FormButton.Location = New-Object System.Drawing.Size(400,10)
$FormButton.Size = New-Object System.Drawing.Size(100,20)
$FormButton.Text = «Проверить»
$window_form.Controls.Add($FormButton)

Теперь к созданной кнопке привяжем скрипт проверки, которые должен вызываться при щелчке на кнопке (событие Add_Click). Для преобразования даты из формата TimeStamp в нормальный вид воспользуемся функцией [datetime]::FromFileTime.

$FormButton.Add_Click(
<
$FormLabel3.Text = [datetime]::FromFileTime((Get-ADUser -identity $FormComboBox.selectedItem -Properties pwdLastSet).pwdLastSet).ToString(‘dd mm yy : hh ss’)
>
)

Запустите PowerShell скрипт. Как вы видите, он заполняет выпадающий список именами учётных записей из AD. Если вы выберите нужную учетную запись пользователя и нажмите на кнопку, в поле отобразится время последней смены пароля данного пользователя в Active Directory.

Аналогичным образом вы можете создать следующие графические элементы на форме:

  • CheckBox
  • RadioButton
  • TextBox
  • ChekedListBox
  • GroupBox
  • ListBox
  • TabControl
  • ListView
  • TreeView
  • DateTimePicker
  • TrackBar
  • PictureBox
  • ProgressBar
  • HScrollBar
  • VScrollBar
  • ContextMenu
  • Menu
Читайте также:  Как запустить win приложение под mac os

Для вывода диалогового окна с уведомлением пользователю можно испоьзоват следующий код:

[System.Windows.Forms.MessageBox]::Show(«Запущен процесс расчета»,»Предупреждение»,0)

Для более удобного и быстрого создания графических элементов для PowerShell форм вы можете воспользоваться онлайн редактор для создания GUI формы для Powershell : https://poshgui.com/Editor.

С помощью него вы сможете создать красивую форму с необходимыми диалоговыми элементами. И получить готовый код графической формы с разными элементами и кнопками для ваших PowerShell скриптов.

WPF формы для PowerShell скриптов

Иногда, при написании PowerShell скриптов, появляется необходимость отобразить некую форму для ввода каких-нибудь параметров или наоборот для отображения результатов скрипта. Ранее для этого я использовал Windows Forms, но у этого метода есть очевидные недостатки – при создании формы необходимо описывать в коде скрипта каждый элемент формы и его свойства. Недавно натолкнулся на несколько статей от “ Hey, Scripting Guy ”, по использованию форм WPF в скриптах PowerShell. В одной из них описывается способ использования форм WPF, реализованный Крисом Конте. Суть его сводится к использованию отдельного скрипта-загрузчика формы и отдельного файла с xaml-описанием формы. В данной статье я хочу показать как легко создавать и использовать формы WPF в своих скриптах.

Необходимые инструменты

Для создания скриптов с формами WPF нам понадобится:

Создаем форму

Для создания формы очень удобно пользоваться Visual Studio Express 2013/2014 for Windows Desktop. Создаем новый проект Visual C# –> Windows –> WPF Application и рисуем там форму с необходимыми нам контролами. Я создал для примера такую:

Изменения, которые я внес:

  1. У самой формы я изменил заголовок (свойство Title) и размеры (свойства Height и Width)
  2. На форму поместил Label в свойство Content которой поместил текст “Это форма запущенная из под Powershell”, а так же изменил размер текста на 24pt
  3. Кнопка Button с текстом “Change” в свойстве Content
  4. Кнопка Button с текстом “Exit” в свойстве Content

В итоге мы получаем XAML текст с нашей формой

Это практически готовый XAML для использования его в нашем скрипте, единственное что нужно сделать – это удалить x:Class=“test.MainWindow” и сохранить его отдельном файле с расширением .xaml (например MyForm.xaml).

Загрузка формы

Для того что бы загрузить нашу форму Крис написал отличный скрипт который я публикую ниже.

Скрипт принимает в качестве параметра $XamlPath путь к файлу XAML. Помещает его содержимое в глобальную переменную $xmlWPF. В блоке try-catch призводится попытка загрузить сборки WPF и в случае ошибки сообщается о невозможности загрузить данные сборки. После чего в глобальную переменную $xamGUI загружается форма из переменной $xmlWPF c помощью сборки Windows.Markup.XamlReader. О последнем блоке ($xmlWPF.SelectNodes…) я расскажу чуть позже. Сохраним данный скрипт под именем loadForm.ps1 и поместим вместе с файлом MyForm.xaml.

Использование скрипта загрузки формы

Теперь нам осталось только воспользоваться плодами нашей работы. Создаем в Windows Powershell ISE (или другой IDE разработки, например PowerGUI) новый скрипт powershell и помещаем его в ту же папку, где и предыдущие файлы. Назовем его к примеру Main.ps1. Воспользуемся скриптом Криса что бы загрузить нашу форму:

Теперь если мы запустим это скрипт то увидим что наша форма появилась на экране.

Программирование событий формы

Мы смогли запустить нашу форму, однако пока что толку он нее очень мало, так как она мало функциональна. Нам нужна возможность определять события элементов формы (нажатие кнопок, и т.д.). Однако что бы как то обратиться к элементам формы нам нужны переменные со ссылками на объекты. Тут то нам и пригодится последний блок скрипта loadForm.ps1:

Читайте также:  Bootcamp macbook air 2011 windows 10

Этот блок делает обход всего дерева xaml и при нахождении аргументов типа Name создает переменные со ссылками на объекты (контролы) нашей формы.

Следовательно нам при создании формы нужно указывать имена (свойство Name) тех контролов, с которыми мы хотим в дальнейшем так или иначе взаимодействовать. Откроем файл нашей формы в текстовом редакторе, ISE или Visual Studio и добавим контролам имена, я дал например такие:

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

Сохранив наш новый код XAML в файл MyForm.xaml мы можем перезапустить наш скрипт Main.ps1, после чего увидим, что скрипт loadForm.ps1 создал переменные $btnChange, $btnExit.

Обратите внимание на тип переменной $btnChange – это [Button], так что это действительно ссылки на объекты формы. Теперь мы можем добавить код для событий наших контролов. Например для того что бы корректно работала кнопка Exit, мы должны закрывать форму при нажатии на кнопку. Это достигается через добавление кода для события Click:

Ну а что бы кнопка $btnChange меняла текст контрола Label1 добавим и ей код для события Click:

Теперь запустив наш скрипт мы можем убедиться в том, что наши кнопки теперь работают.

Собственно это все на сегодня. Если будет интерес к этой теме – буду рад написать еще несколько статей.

Form. Show(IWin32Window) Метод

Определение

Показывает форму с указанным владельцем. Shows the form with the specified owner to the user.

Параметры

Любой объект, который реализует IWin32Window, представляющий окно верхнего уровня, которое станет владельцем этой формы. Any object that implements IWin32Window and represents the top-level window that will own this form.

Исключения

Отображаемая форма уже отображена. The form being shown is already visible.

-или- -or- Форма, указанная в параметре owner , совпадает с отображаемой формой. The form specified in the owner parameter is the same as the form being shown.

-или- -or- Отображаемая форма отключена. The form being shown is disabled.

-или- -or- Отображаемая форма не является окном верхнего уровня. The form being shown is not a top-level window.

-или- -or- Отображаемая в виде диалогового окна форма уже является модальной формой. The form being shown as a dialog box is already a modal form.

-или- -or- Текущий процесс не выполняется в интерактивном пользовательском режиме (дополнительные сведения см. в описании свойства UserInteractive). The current process is not running in user interactive mode (for more information, see UserInteractive).

Комментарии

Этот метод можно использовать для вывода не модальной формы. You can use this method to display a non-modal form. При использовании этого метода Owner свойство формы устанавливается в значение owner . When you use this method, the Owner property of the form is set to owner . Немодальная форма может использовать Owner свойство для получения сведений о форме-владельце. The non-modal form can use the Owner property to get information about the owning form. Вызов этого метода идентичен заданию Owner Свойства немодального объекта и последующему вызову Show() метода. Calling this method is identical to setting the Owner property of the non-modal and then calling the Show() method.

Читайте также:  Перенос linux hyper v

Отображение формы эквивалентно присвоению Visible свойству значения true . Showing the form is equivalent to setting the Visible property to true . После Show вызова метода Visible свойство возвращает значение true до тех пор, пока Hide не будет вызван метод. After the Show method is called, the Visible property returns a value of true until the Hide method is called.

In PowerShell Form.Show() does not work right, but Form.ShowDialog() does

I am trying to display an image via powershell. I made a script based on this forum post.

If I use ShowDialog() it works fine, except the powershell execution stops while the dialog is up. However, that is by design for a modal dialog. If I call Form.Show() in PowershellISE the form shows up, but freezes and cannot be moved or dismissed. Behavior is similar if I copy and past the code to a powershell console.

How do I make the dialog non-modal, and not freeze.

4 Answers 4

First Answer Why it appends.

In a Windows graphic program the thread which create a Window must loop in a message pump in order to redistribute (translate) messages coming from the user action to events in his Windows.

In a modal window, the modal code that handles the window display runs its own message pump loop and doesn’t return until the window is closed. That’s why the code after ShowDialog() won’t execute until the window is closed.

Show() , just ask to show the Window, but if there is no pump loop to manage the messages coming from user action, it just freezes.

Second a simple way to have two threads

The CmdLet start-job use another thread from the pool allocated by Powershell so it makes the dialog non-modal, and it does not freeze.

There are ways to make this work, but nothing is worth spending five hours explaining on an open forum. There are other free, shrink-wrapped ways to do this on powershell. Most notably with the free WPF powershell toolkit: Show-UI at http://showui.codeplex.com/ (previously known as WPK and/or PowerBoots — they are merged now.)

If your goal is actually to not block the interactive console when an image is shown then you still can use the script as it is with ShowDialog but you should start it using, for example, Start-Job . Thus, the dialog is still modal but it blocks execution in another runspace. The main runspace still can be used for invoking other commands.

Caveats: 1) You should close all opened dialogs before closing the interactive console. 2) If you care, you should remove completed jobs yourself (when a dialog is closed a job that started it still exists).

I use a similar approach in my custom host and it works fine. I also tested it with the script from your link. I changed it slightly so that it is called show-image.ps1 and accepts a file path as a parameter.

This command shows an image and blocks the calling runspace:

This command shows an image and does not block the calling runspace:

Оцените статью