GUI на Powershell

Powershell — довольно мощное средство автоматизации, которое позволяет «прозрачно» использовать объекты .NET Framework. Это позволяет очень легко использовать такие объекты, как GUI интерфейс для ваших скриптов.
Рассмотрим, как можно создать форму и расположить на ней стандартные элементы формы.

Элементы которые я создал на форме:

Form

Label

button

CheckBox

RadioButton

ComboBox

TextBox

ChekedListBox

GroupBox

ListBox

TabControl

ListView

TreeView

DateTimePicker

TrackBar

PictureBox

ProgressBar

HScrollBar

VScrollBar

ContextMenu

Menu

Получилась вот такая форма:

Создание Формы на Powershell
Создание Формы на Powershell

Что бы получить эту форму, надо выполнить следующий скрипт:

 

Рассмотрим этот код подробнее:

 

Определяем в сеансе Powershell класс «System.Windows.Forms» именно он нужен, для создания формы, и в нём же находятся элементы формы.

 

Forms

 

Создаём форму $main_form, которую мы будем наполнять управляющими элементами.

 

Это текст будет отображаться в заголовке формы $main_form.

 

Минимальная ширина формы $main_form.

 

Минимальная высота формы $main_form.

 

Форма будет автоматически растягиваться, если элементы расположенные на форме выйдут за границуМинимальная ширина или Минимальной высоты формы.

 

$main_form.ShowDialog()

В конце скрипта мы отобразим форму $main_form.

 

Label

 

Создаём метку $Label

 

Задаём текст, который будет выводится в метке $Label.

 

Задаём расположение метки $Label, относительно формы.

 

Включаем авторастягивание метки $Label если её содержимое выйдет за границы видимости.

 

Добавляем метку $Label на форму

 

Button

Создаём элемент, кнопку $button.

 

Задаём текст котрый будет написан на кнопке $button.

 

Определяем расположение кнопки $button.

 

Добавляем кнопку $button на форму.

 

CheckBox

 

Объявляем элемент флажка $CheckBox

 

Задаём текст который будет виден на элементе с права от флажка $CheckBox

 

Разрешаем элементу увеличивать размер, если части элемента выйдут за переделы его видимости.

 

Устанавливаем флажёк в положение $true, будет отображаться галочка

 

Устанавливаем полжение элемента $CheckBox на форме

 

Добавляем элемент $CheckBox на форму

 

RadioButton

 

Объявляем элемент $RadioButton

 

Устанавливаем полжение элемента $RadioButton на форме

 

 

Задаём текст, который будет виден на элементе $RadioButton.

 

Разрешаем элементу $RadioButton увеличивать размер, если части элемента выйдут за переделы его видимости.

 

Добавляем элемент на форму

 

ComboBox

Объявляем элемент $ComboBox

 

Задаём список элемента $ComboBox, который будет виден, в выпадающем списке, по умолчанию видно первое значение.

 

Устанавливаем полжение элемента $ComboBox на форме

 

 

Добавляем элемент $ComboBox на форму

 

TextBox

 

Объявляем элемент $TextBox

 

Устанавливаем полжение элемента $TextBox на форме

 

Задаём текст, который будет вбит в элементе $TextBox, в дальнейшем его можно будет редактировать.

 

Добавляем элемент $TextBox на форму

 

CheckedListBox

 

Объявляем элемент $CheckedListBox

 

Добавляем внутреннии элементы  в элемент $CheckedListBox.

 

Устанавливаем полжение элемента на форме

 

Добавляем элемент $CheckedListBox на форму

 

GroupBox

 

Объявляем элемент $GroupBox

 

Задаём текст, который будет виден в заголовке элемента $GroupBox.

 

Разрешаем элементу $GroupBox автоматически увеличить свои размеры, если находящиеся в нём элементы выходят за границу видимости.

 

Устанавливаем полжение элемента$GroupBox на форме

 

Создаём элемет кноку $button2 и помещаем его внутрь элемента GroupBox, при этом координаты свойства Location будут относительно верхнего левого края объекта GroupBox

 

Создаём элемет флажок $CheckBox2 и помещаем его внутрь элемента $GroupBox, при этом координаты свойства Location будут относительно верхнего левого края объекта $GroupBox.

 

Добавляем элемент $GroupBox на форму

 

ListBox

 

Объявляем элемент $ListBox

 

Устанавливаем полжение элемента $ListBox на форме

 

Создаём строчки в $ListBox с именами ‘ListBox’,  ‘2’, ‘3’

 

Добавляем элемент $ListBox на форму

 

TabControl

 

Объявляем элемент $TabControl

 

Объявляем новый элемент вкладка $TabPage1

 

Присваиваем элементу вкладка $TabPage1 текст, он будет отображаться в названии вкладки.

 

Объявляем элемент $TabLabel и размещаем его на вкладке $TabLabel при этом координтаы элемента $TabLabel.Location будут относительно левого верхнего угла вкладки $TabLabel

 

Объявлем ещё одну вкладку $TabPage2 и подписываем её.

 

Добавляем эти вкладки на элемент $TabControl

 

Устанавливаем полжение элемента $TabControl на форме

 

Добавляем элемент $TabControl  на форму

 

ListView

 

Объявляем элемент $ListView

 

Объявляем элементы которые будут находится в $ListView с видимым отображением в ввиде текста «—=1=—«, «—=2=—«, «—=3=—» и «—=4=—»

 

Добавляем эти элементы на $ListView

 

Устанавливаем полжение элемента $ListView на форме

 

Добавляем элемент $ListView на форму

 

TreeView

 

Объявляем элемент дерева $TreeView

 

Создадим первый узел $TreeViewNode с отображаемым текстом в $TreeView «1»

 

Тогда мы можем добавить в узел $TreeViewNode другой узел с отображаемым текстом «2»

 

Добавляем узел «3» к корню дерева

 

Устанавливаем полжение элемента на форме

 

Добавляем элемент $TreeView на форму  $main_form

 

DateTimePicker

 

Объявляем элемент $DateTimePicker

 

Устанавливаем полжение элемента $DateTimePicker на форме

 

Добавляем элемент $DateTimePicker на форму $main_form

 

TrackBar

 

Объявляем элемент ползунок $TrackBar

 

Устанавливаем полжение элемента $TrackBar на форме

 

Разрешаем элементу $TrackBar увеличивать размер, если он не будет вмещаться в ввидимую часть.

 

Устанавливаем значение $TrackBar на 5 деление.

 

Добавляем элемент $TrackBar на форму $main_form

 

PictureBox

 

Объявляем элемент $PictureBox

 

Загружаем картинку ‘D:\favico.jpg’ в элемент $PictureBox

 

Устанавливаем полжение элемента $PictureBox на форме

 

Добавляем элемент $PictureBox на форму $PictureBox

 

ProgressBar

 

Объявляем элемент $ProgressBar

 

Устанавливаем полжение элемента $ProgressBar на форме

 

Устанавливаем значение $ProgressBar в 50

 

Добавляем элемент $ProgressBar на форму $main_form

 

HScrollBar

 

Объявляем элемент $HScrollBar

 

Устанавливаем размер элемента $HScrollBar

 

Устанавливаем полжение элемента $HScrollBar на форме

 

Добавляем элемент $HScrollBar на форму $main_form

 

VScrollBar

 

Объявляем элемент $VScrollBar

 

Устанавливаем размер элемента $VScrollBar

 

Устанавливаем полжение элемента $VScrollBar на форме

 

Добавляем элемент $VScrollBar на форму $main_form

 

ContextMenu

 

Объявляем временный элемент $ContextMenu

 

Добавляем первый пункт $ContextMenu

 

Добавляем второй пункт $ContextMenu

 

Присваиваем контекстному меню форме $main_form контекстное меню $ContextMenu

 

Menu

 

Объявляем временны элемент $Menu

 

Объявляем первый элемент меню $menuItem1

 

Изменяем отображаемый текст $menuItem1

 

Добавляем этот элемент $menuItem1 в меню $Menu

 

Объявляем ещё один элемент меню $menuItem2, и изменяем его отображаемый текст

 

Добавляем элемент $menuItem2 в $menuItem1

 

Объявляем новый элемент $menuItem3 в меню $Menu

 

Присваиваем Меню формы $main_form значение временному меню  $Menu

 

 

Отображает форму $main_form

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

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

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

    • И вам доброго времени суток. Спасибо за лестный отзыв. 🙂
      С комбо боксом всё просто, надо поменять стиль DropDownStyle. Для моего примера это будет выглядеть так:

    • Для того, что бы форма была всегда поверх всех окон у формы есть параметр «TopMost» . Для моего примера это выглядело бы так:

  • Спасибо, за совет, с активной формой уже сам нашел, во правда она все одно по верх запущенного окна powershell ise не выскакивает, но видимо это связанно с тем что окно ise тоже активно так как ждет команду… За стиль отдельно, еще раз спасибо 🙂

  • нашел на msdn вот такую штуку, она делает окно активным, и соответственно поверх всех, не знаю насколько интересно будет 🙂
    $obj_form.Add_Shown({$obj_form.Activate()})
    [void]$jbj_form.ShowDialog()

    • Если решусь продолжать писать статью про форму обязательно напишу. Но обычно мне не нравятся формы которые закрывают часть экрана и не дают ничего с этим делать. Обычно такие формы трояны-вымогатели используют. 🙂

  • зато эффективно, если убрать кнопки свернуть, закрыть… оставив только ок с нотифаем в сторону админа, что ознакомлены. ни кто потом не скажет, вы не предупредили и из-за вас у меня вся работа рухнула 🙂

    • Антон, а вот уже чисто академический вопрос, как можно реализовать следующее, не кое окно, где стоит текст, что то вроде «ожидайте идет обработка», а сам скрипт продолжал обрабатываться, вот в таком виде у меня не работает:
      [void]$excl_form.ShowDialog()
      тут какой то блок кода
      $excl_form.Close()
      Можете что посоветовать?

      • Можно на ты, как ни как коллеги. 🙂

        как то очень тяжко понимаю «сам скрипт продолжал обрабатываться» и «у меня не работает» 🙂

        Так что скажу чтонибудь сумбурное : «закрывать окно по таймеру?» или лучше так: «таймер?» или «System.Threading.Timer».

        Я не издеваюсь у меня настроение хорошее… скоро домой 🙂

        • Поясню.. я не понимаю что не нравится в данном [void]$excl_form.ShowDialog()
          тут какой то блок кода
          $excl_form.Close()

      • А! во понял!
        запускай «тут какой то блок кода» в событии формы $excl_form. В креэйте например и в конце «тут какой то блок кода» $excl_form.Close()
        И всё будет.

        • пробовал взять тот блок кода внутрь скобок, не отрабатывает….
          т.е. выглядит так
          [void]$excl_form.ShowDialog( тут идет код. который обрабатывает данные из экселевской таблицы )
          $excl_form.Close()

          Собственно это не важно, просто хотел, пока идет обработка экселевской таблицы и диалоговые окна не появляются, показывать окно без кнопкой с фразой «Ждите…»
          Потом это окно гасить и уже пошли диалоговые….

          Пока ждал ответа, назрел еще один вопрос…шерстил в гугле. не нашел…

          Вот смотри…создаю форму с текст боксами и расшифровкой рядом, фактически их 10-ть текст боксов все однотипные и отличаются только координатами расположения. думал прогнать циклом ну что бы у каждого текстбокса было уникальное имя
          типа $textbox1 = New-Object “System.Windows.Forms.TextBox”
          $textbox2= и т.д….Рельно как то реализовать это в цикле, что бы не руками каждый текст бокс создавать?
          т.е. авто создание переменной где $textbox -это фактически константа, а цифра к ней просто присоединяется?

          • да конечно реально, так и делается 🙂
            делается массив(например $textbox) и в цикле прогоняется создание объектов с нужными параметрами.
            Событие на них вешается одно (например клик мыши) а там смотрится какой объект вызвал данное событие.

  • Видимо под вечер мозги, да и глаза в кучу, не совсем понял, можешь пояснить на примере?
    Т.е. надо создать три текст бокса стоящих друг над другом с дефолтовым значением 0, у любого из них в диалоговом окне мы можем поменять значение. Можем и у всех. При нажатии пимпы ок, все значения трех текстбоксов передаем переменным…

    Хотя я наверно понял что ты имеешь ввиду, в массив загоняем эти десять переменных…типа текстбокс1, текстбокс2 и т.д…верно?

    • да, именно так. текстбокс[1], текстбокс[2] и т.д пример не могу… мне с ребёнком надо играться 🙂 ток завтра…

      • Здравствуйте, только начинаю разбираться с PowerShell и кодами в целом, хотел поинтересоваться, каким образом можно запустить дальше данные которые вводятся в TextBox. Сделал 2 поля логин и пароль, под ними кнопки Ок и Cancel и хотел, чтобы после ввода данных в поля TextBox1 и TextBox2 при нажатии кнопки ОК, данные сохранялись или передавались в другой файл, а при нажатии кнопки Cancel удалялись, не могу найти решение на просторах интернета. Может плохо ищу. Извините, если вопрос не по теме.

        • А что должна делать вот эта строка?
          $TextBox = $credentials.Password | ConvertFrom-SecureString | Set-Content «C:\Users\IvanMB\Desktop\1.txt»
          В итоге в $TextBox будет результат вот этой команды Set-Content «C:\Users\IvanMB\Desktop\1.txt»
          данные из текст бокса лежит вот здесь $TextBox.Text. Пример использования:

  • Ну будет время завтра, все-таки кинь пример…Спасибо за помощь.

  • Тот пример который ты хотел, скучный при нажатии кнопки визуально ничего не происходит 🙂
    Поэтому при нажатии кнопки меняется значения текста в текст-боксах. Я думаю ты с лёгкостью переделаешь этот пример под себя.

    • Спасибо, правда не понял зачем вот это..
      # при нажатии клавиши запускается цикл пробегающий все TextBox`ы
      for($i=0; $i -lt $CountTextBox; $i++)
      {
      # присваиваем тексту текст бокса значение переменной $i
      $TextBox[$i].Text = [string]$i
      }
      }
      Как мои вчерашние опыты показали, в отличии от того же выпадающего списка, где подобное нужно, что бы текстовое значение из списка передать дальше в скрипт, после закрытия формы. Значение чек боксов прекрасно доступны и потом. И собственно я их и использовал дальше в скрипте напрямую, как $TextBox[0].Text и т.д.

      Еще раз спасибо за пример!.

      И вот поэтому можешь подробнее пояснить?

      «пробовал взять тот блок кода внутрь скобок, не отрабатывает….
      т.е. выглядит так
      [void]$excl_form.ShowDialog( тут идет код. который обрабатывает данные из экселевской таблицы )
      $excl_form.Close()

      Собственно это не важно, просто хотел, пока идет обработка экселевской таблицы и диалоговые окна не появляются, показывать окно без кнопкой с фразой «Ждите…»
      Потом это окно гасить и уже пошли диалоговые….»

      • Чтоб пример написать, скажи а как ты обрабатываеш события? мне просто способ $button.add_Click({Click_Button}); не нравится в msdn написано, что только для внутреннего использования в корпорации 🙂

        • В общем лан.. буду пользоваться этими костылями.

          Вместо татам функцию или код вставить надо.
          start-sleep( 10) нужен чтоб форма успела отобразиться нормально.
          Тоесть на событие активация формы мы ставим её закрытие, а в событие закрытия вставляем нужный код.
          После выполнения кода форма сможет благополучно сама закрыться.

      • > Спасибо, правда не понял зачем вот это..
        > # при нажатии клавиши запускается цикл пробегающий все TextBoxы
        > for($i=0; $i -lt $CountTextBox; $i++)
        > {
        > # присваиваем тексту текст бокса значение переменной $i
        > $TextBox[$i].Text = [string]$i
        > }
        > }
        Это просто показать, что кнопка работает. и просто изменяю значение $TextBox
        ов

  • Ну вот такое для выпадающего списка
    $button.Add_Click({$selected_der.Text = $dropdown_list.SelectedItem.ToString(); $der_form.Close()})

    А такое вот для текст бокса
    $button_end.Add_Click({$end_form.Close()})

  • Да, увидел. Спасибо! Все понятненько 🙂

  • Очень громоздко и жутко. Вот так надо:
    Сохраняем этот xml в файлик

    И далее на повершеле:

    ВО КАК НАДА 

    • а можно текст xml, для полноты комментария? и текст между тегами <pre></pre> пожалуйста размести, что бы не пропал.

    • По моему мнению способ с xml удобен, когда у тебя большая форма.
      А если ты пишешь скрипт, в котором у тебя на форме один показатель активности, с кнопкой стоп. Это уже не слишком то и надо.
      Я так и не начал воспринимать PowerShell как язык программирования. Для меня это средство написать ёмкие консольные приложения. В которых форма это по большей степени исключение, нежели инструмент первой необходимости.

  • У меня к вам вопрос.
    Я создал форму состоящую из определённого количества кнопок, а как мне реализовать открытие других скриптов при нажатии кнопки?(каждая кнопка соответствует определённому скрипту)

    • Там выше в комментариях вот такая конструкция : «$button.add_Click({Click_Button});» Где вместо Click_Button код который должен выполниться при нажатии кнопки, но мне не нравиться этот метод, т.к. на msdn он указан как для внутреннего использования…
      А как правильно я так и не нашёл, как реализовать… Надо вернуться к этому вопросу…

      • Но как вариант использовать можно?

        • Да, но возможны проблемы в дальнейшем, при переходе на новые версии Net. Framework`а …. в будущем..

          • А и ещё вопрос.
            За место ({Click_Button}) название скрипта или прям сама строчка кода, которая нужна для выполнения?

            • Можно прямо между фигурных скобочек код писать, можно вынести код в отдельную функцию и в фигурных скобочках её вызывать.
              Пример формы в которой при нажатии кнопки к названию кнопки добавляется текст «1»

  • А как-то с помощью кода можно при клике сделать открытие файла?

    • Не понял вопроса.. файл надо открывать чем то %)
      Например открытие файла с помощью блокнота C:\1.txt:

      Или например смотрим содержимое файла и выводим его содержимео в… консоль…

      • Спасибо большое вам за помощь.)Спасли меня на практике.)
        Дали задание сделать что-то подобное,а я не умею._
        Благодаря вам разобрался и научился.)

  • Подскажите, в какой среде кроме PowerShell ISE можно писать код?

  • кроме Windows PowerShell ISE
    есть:
    Visual Studio Code
    (SAPIEN) PowerShell Studio 2016,PrimalScript2016,
    PowerGUI
    PowerShell Analyzer
    PowerShell Plus

    да хоть Notepad++

    Но вопрос находится в статье для GUI, поэтому вы наверно хотите услышать про Windows Presentation Foundation который находится в Visul Studio. И с помощью которого можно создавать xml c описанием GUI, которое можно подключить к Power Shell.

  • Для таких как я «е» -это Академия.Возможно Вы посоветуете использование Windows.Forms используя не только для создания «формы» как таковой,но и к обращению к математической её части.
    С признательностью Anatol.

  • Хотел бы уточнить про «е» это вы про «ё»?

    И ещё не совсем понял про математическую часть формы.
    У меня есть статья про часть свойств формы http://coolcode.ru/izmenyaem-vneshniy-vid-system-windows-forms-form/.
    Вы про такие статьи ?

    Я сначала хотел попытаться описать все объекты формы, но из за не достатка времени меня унесло в другие направления. Более интересные людям. Сейчас я пытаюсь разобраться с Arduino. И пишу переводы для CodeCombat детей завлекать во время каникул. 🙂 А то Июнь Июль Август совсем скучно, никто не заходит и ничего не пишут. 🙂

    Так что по подробнее что вы хотите увидеть, а лучше напишите статью вы. За одно и научитесь я так и делаю. 🙂

  • По поводу «ё» Вы совершенно правы, извиняюсь за ошибку. Что касается «математической части», то меня интересуют такие свойства как вычисление sin x и всё такое прочее. PS требует задание аргумента в радианах и пришлось сотворить программку перевода радиан в градусы используя разложение функций в ряд Маклорена. Хотелось бы работать напрямую без всяких разложений во всяческие ряды.

    • М…. здесь сложный момент… вы явно выбрали не тот инструмент. 🙂
      Вам нужен настоящий язык программирования. 🙂
      вот вы в командной строке стали бы вычислять sin? … надеюсь это не для генерации логинов AD-шных учёток:)
      В любом языке программирования есть своя библиотека Math в какой-нубудь форме.
      Не исключение и .NET который можно использовать в PowerShell. И вычисление синуса в PowerShell можно записать так:

      Подробнее про библиотеку Math от .NET можно посмотреть здесь
      Но повторюсь инструмент явно не тот.

  • Увы,так называемые настоящие языки программирования, в частности C++ с столь же ущербен, что и PS.Приходилось и там использовать ряд Маклорена. К Вам же огромная просьба: не оставляйте намерение по описанию(желательно с примерами) всех объектов формы. Ваш «ё» удивительно приятное исключение на достаточно сером фоне сведений по созданию форм и внятного описания пространства имён.
    С признательностью Anatol/

  • Вы всегда можете стать автором на этом сайте. И написать данные статьи самостоятельно. 🙂
    А я в .net разочаровался… мне будет сложно заставить себя тратить много времени на описание этого… не побоюсь этого слова фреймворка….
    Если я и начну описывать, как создавать формы то в первую очередь на QT давно смотрю в сторону данной библиотеки. 🙂

  • Добрый день!
    Написал рекурсивный парсер файлов xml .
    Все бы ничего, работает на уровне консоли..
    но я решил написать гуишку для вывода и незадача

    Код парсера

    $path=get-childitem -dir
    gci $path -recurse
    -include *.xml

    | Foreach {
    $file = $_;
    $f_path=$file.DirectoryName +»\»+ $file.Name
    }
    #——————reading xml files————————————
    [xml]$xmlfile = Get-Content $f_path | foreach($xmluser in $xmlfile.счетапк.открытиесчетов.сотрудник) {
    Write-Host $xmluser.син ‘|’ $xmluser.фамилия $xmluser.имя $xmluser.отчество ‘|’ $xmluser.ОтделениеБанка ‘|’ $xmluser.ФилиалОтделенияБанка ‘|’ $f_name
    }

    Часть GUI
    $Label = New-Object System.Windows.Forms.Label
    $Label.Text = $_____????______ <- что тут присвоить, я не могу понять
    $Label.Location = New-Object System.Drawing.Point(0,10)
    $Label.AutoSize = $true
    $main_form.Controls.Add($Label)

    вот я и не знаю, как прицепить $xmlfile или цикл foreach к переменной $label.text
    Возможно можно использовать текстбокс с мультилайном…

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *