Опыты на PowerShell с диалоговым окном Windows, или как я едва не залез в дебри .NET

…Вот признайтесь честно, дорогие мои коллеги-скриптологи, кому из вас не хотелось, чтобы скрипт задавал Вам вопросы не в консоли, а в стандартном MessageBox производства Microsoft?

Мне, если не кривить душой — не хотелось, так как испытываю патологическую тягу к консольно-текстовому интерфейсу, а Windows-интерфейс от MS не особо люблю (об этом ещё много строчек будет написано…), но любопытство — штука такая, что однажды оно заставило меня заглянуть за плотный занавес своего обыденного «не хочу, не люблю Windows-стандартные диалоговые окна». Нагуглил по теме немного, осознал суть вопроса. И так всё просто и мило оказалось на деле. (Если бы я знал, в какие дебри чуть не залезу!)

[System.Reflection.Assembly]::LoadWithPartialName(«System.Windows.Forms»)
$Result=[Windows.Forms.MessageBox]::Show(«Hello World!», «Это заголовок окна», `
[Windows.Forms.MessageBoxButtons]::YesNo, [Windows.Forms.MessageBoxIcon]::Question)
If ($Result eq «Yes») { Write-Host «Вы нажали кнопку Yes!» } else {Write-Host «Вы нажали кнопку No!»}

Вначале загружается стандартная сборка из комплекта .Net FrameWork — System.Windows.Forms, которая обеспечивает интерфейс взаимодействия с, простите за масляное масло, интерфейсным API «винды», ну а дальше вызывается функция MessageBox (1-й параметр — текст в окне, второй — заголовок окна, третий — какие кнопки отображать, ну а четвертый, какой значок демонстрировать в окошке. В данном случае показывается знак вопроса).

Как с этим жить дальше — вполне понятно 🙂 Вместо печати на экран вставляете любой необходимый код после условий If/else — и наслаждаетесь результатами.

///////////////////////////////////

А теперь немного побалуемся. Для разнообразия вместо Write-Host в случае Yes можно подставить и что-нибудь навроде «format C:«, благо PowerShell отлично понимает DOS-овские/CMD-шные команды 🙂 😀 Но я предпочел поиграться с иконкой окна. Как я помню аж с времен Windows 3.1 и некоей прибамбасы к Borland Pascal for Windows 7.0, именовавшейся вроде как Resource WorkShop (там была куча красивых цветных кнопок, с головой захвативших мою душу в далёком 1999 году), у таких «информационных» иконок могут быть состояния вроде «Exclamation«, «Stop«. Изменил в последней строчке «Question» на «Exclamation» — и увидел великолепный жёлтый восклицательный знак:

А затем изменил Exclamation на Stop — и увидел красный крестик:

…Не, признаться честно, в 3.1 эта иконка мне нравилась больше, там было аж само слово «Stop» внутри красной фигурки типа шестиугольника (хотя уже и не помню, какой точно).

…Возник соблазн поглядеть, а что находится внутри типа [Windows.Forms.MessageBoxIcon], какие ещё там забавные значки спрятаны? Но при этом ни в коем случае не читать официальную документацию на MSDN, ибо так неинтересно. Лёгких путей наш поезд не ищет! (Такой же соблазн, как в детстве с азартом открывал старинным Resource Workshop’ом первые попавшиеся .dll-шки, и разглядывал содержащиеся внутри них графические ресурсы — иконки, которые помню, ещё можно было экспортировать оттуда в .ico-формат).

Не запуская никаких скриптов, просто в синей, как вечернее небо, консоли PowerShell, вначале набираю:

[System.Reflection.Assembly]::LoadWithPartialName(«System.Windows.Forms») #Это святое, иначе ничего не выйдет!

…затем ввожу:

[Windows.Forms.MessageBoxIcon]

и вижу, что базовый тип System.Enum. Ну это понятно, «энумератор», «коллекция» — так и должно быть, если там внутри содержится некоторый набор типов иконок.

В консоли эта штука через «::Stop» или любое другое «волшебное» слово (Question, Exclamation) возвращает строковое значение:

[Windows.Forms.MessageBoxIcon]::Stop — я увидел слово «Hand»
[Windows.Forms.MessageBoxIcon]::Exclamation —
я
увидел слово «Warning»
[Windows.Forms.MessageBoxIcon]::Questionя увидел слово «Question» 🙂

На самом же деле это не строка конечно, а намного более сложный объект — в чём легко убедиться, пустив квадратную штуку по конвейеру на Get-Member (например, [Windows.Forms.MessageBoxIcon]::Stop | Get-Member) для того, чтобы посмотреть поля и методы этого объекта (и там много чего увидим) — но подстановка в исходный скрипт вызова диалогового окна обычных строк-слов «Hand», или «Warning», или «Question» в двойных кавычках даёт тот же самый результат, что и «квадратно-скобочные» здоровенные конструкции 🙂 Мелочь, а приятно 🙂

…Так, всё это здорово, конечно, но ведь я так и не нашел ещё ответа на вопрос, а какой вообще набор иконок существует для диалогового окна? А довольно просто узнать — берем базовый тип «энумераторов» (коллекций) System.Enum, у него есть метод GetNames(), на который в качестве параметра пускаем [Windows.Forms.MessageBoxIcon] и получаем имена существующих полей:

[System.Enum]::GetNames([Windows.Forms.MessageBoxIcon])

None
Hand
Error
Stop
Question
Exclamation
Warning
Asterisk
Information

О сколько возможных значков, а?! Но не обольщайся, Никита, ты глянь лучше на значения этих полей (которые тебе и скажут, сколько реально ты значков можешь увидеть). Так… по очереди руками перечислять — это скучно. А вот через крутой оператор ForEach-Object пустить, это по-нашенски! По PowerShell-овски!

[System.Enum]::GetNames([Windows.Forms.MessageBoxIcon]) | ForEach-Object { [Windows.Forms.MessageBoxIcon]::$_
}

None
Hand
Hand
Hand
Question
Warning
Warning
Asterisk
Asterisk

То есть, члены с именем <A> имеют значение <B>:

[]::None=None
[]::Hand=Hand
[]::Error=Hand
[]::Stop=Hand
[]::Question=Question
[]::Exclamation=Warning
[]::Warning=Warning
[]::Asterisk=Asterisk
[]::Information=Asterisk

…Увы, количество реальных значков на самом деле не так уж велико, как ожидалось исходя из количества членов коллекции [Windows.Forms.MessageBoxIcon]. Ну да ладно, мне ли расстраиваться? Надо будет — свои значки-иконки для диалогового окна нарисую, а ещё лучше, забью на Microsoft-интерфейс и создам свой собственный, консольно-текстовой. Но это уже тема отдельного опыта…

Автор: admin

Кандидат химических наук, работающий системным администратором :)

Опыты на PowerShell с диалоговым окном Windows, или как я едва не залез в дебри .NET: 4 комментария

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

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

*