tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

PowerShellでWPFしたい Part1 - WPK編

前回の予告通り、今回はPowerShellでWPFに関する記事です。 PowerShellは、ご存じの通り、.Net Frameworkを基盤としたシェル環境です。 シェル環境というとCUIだけと思いがちですがPowerShell、.Netの力を借りてGUI表示も出来るわけです。 cmdの頃には考えられなかったですねー (棒 PowerShellでGUIといえば、WinFormsが今でも良く紹介されています。 が…WinFormsは嫌です。WPFしたいです。 今回、WPF初学者の身ですが、PowerShellでWPFによるGUI表示をする手法とサンプル例をご紹介できればと思います。  

そもそもShellなのにGUI?

PowerShellでGUIをするメリットは、人によって色々あると思います。 私の場合は、以下がメリットに感じています。  
  1. PowerShellコマンドレットを、ソースで書けばそのままGUIに反映して利用できること。
  2. PowerShellのCUIに親しめないユーザーにもGUI表示することで親しみやすくする。
  3. CUIに比べて、ユーザー視点では表示が見やすい…らしい?です。(棒
  帝国兵様からも、このようなお言葉いただき安堵したのは内緒です。  

各PowerShellで利用している.Net Frameworkバージョン

一応確認です。PowerShell v2.0とv3.0で利用している.Net Framworkバージョンは以下です。
PowerShell 2.0 = .Net Framework = 2.0
PowerShell 3.0 = .Net Framework = 4.0
※.Net4.0かよ-、という突っ込みは止めてあげましょう。 ※私の記事は、PowerShell V3.0を前提に書かれています。V2.0とはインテリセンスやISEなどで表示が異なりますのであらかじめご了承ください。  

PowerShellでWPF手法には何がある?

PowerShellでWPFをするにあたり、以下の3つを紹介します。
WPK       #第1回
Show-UI   #第2回
XAML      #第3回
記事が長くなりすぎるので、各内容で記事を分けます。 Part1の今回はWPKです。  

WPKの紹介

WPKは、WPF PowerShell Kitの事を指します。 MSDNでWPKに関して詳しく紹介されています。(英語)
About the PowerShell Pack

必要要件

WPKを利用するには、以下の要件を満たす必要があります。
  1. PowerShell V2.0以上 (ISE含む)
  2. WPKのインストール(Import-Moduleコマンドレットで可能)
  3. Set-Execution PolicyでRemoteSignedなど外部ps1スクリプトの読み込み許可
 

PowerShell V2.0(ISE含む)以上のインストールについて

Windows 7/8、Windows Server 2008R2/2012をお使いの場合は、PowerShell V2.0が既にインストールされていますので、2と3のみ気にすればWPKは利用できます。 ただ、Windows Management Framework 3.0(WMF3.0)がリリースされていますので、PowerShell V3.0に上げられることを推奨はしますが…(自己責任でどうぞ
Download Windows PowerShell
  Windows Vista/2008の場合、PowerShell V1.0のみがデフォルトでインストールされています。(XPや2003の場合は、PowerShell自体が標準では入っていません。) この場合、Windows Management Framewaork 2.0(WMF 2.0)のインストールが必要です。
Windows Management Framework Core パッケージ (Windows PowerShell 2.0、WinRM 2.0)

WPKのインストール

先ほどのAbout the PowerShell Packのリンク先にあるタブでDownloadからPowerShellPack.msiをダウンロードして、msiを実行、インストールします。 これで、PowerShellの所定のmodule配置パスに9つのモジュールが設置されてます。 モジュールは設置されただけですので、WPKを利用する場合は、別途PowerShell無いでImport-ModuleにてWPKを読み込ませる必要があります。(それは後ほど)

Set-Execution PolicyでRemoteSignedなど外部ps1スクリプトの読み込み許可

これに関しては、以前の記事にまとめていますので参照してください。
PowerShellスクリプト(.ps1)を初回実行する際のスクリプト実行セキュリティ・ポリシーについて

WPKでインポートされるモジュール

インストールにより、以下のPowerShellのModule Pathに各種WPK Moduleがインストールされます。
%USERPROFILE%\Documents\WindowsPowerShell\Modules
PowerShellのもう一つのModule Pathである%WINDIR%下にはインストールされません。
%WINDIR%\system32\WindowsPowerShell\v1.0\Modules
msiでインストール後の%USERPROFILE%\Documents\WindowsPowerShell\Modulesファイル一覧
DotNet
FileSystem
IsePack
PowerShellPack
PSCodeGen
PSImageTools
PSRSS
PSSystemTools
PSUserTools
Setup
TaskScheduler
WPK
About the Windows 7 Resource Kit PowerShell Pack.docx #ファイル
Readme1st.txt #ファイル
Writing User Interfaces with WPK.docx #ファイル
About the PowerShell Packでは、インストールされるModuleは以下としています。
WPK #UIを作るための600以上のモジュール
TaskScheduler #スケジュールタスクの管理モジュール
FileSystem #ディレクトリやファイル、ディスクの管理
IsePack  # ISEモジュール
DotNet  # PowerShell, .Net, COMにおける型に関するモジュール 
PSImageTools  # イメージの変換、回転、縮尺、切り抜き、イメージメタ情報に関するモジュール
PSRSS  #RSSフィードに関するモジュール
PSSystemTools  #OSやHWに関する情報取得モジュール
PSUserTools  # ユーザーやプロセスに関するモジュール
PSCodeGen  #PowerShellスクリプト、C#コード、P/Invokeの生成に関するモジュール

WPKモジュールのアンインストール

一般的なプログラム同様、プログラムと機能からアンインストールできます。
Control Panel | Programs and Features | PowerShellPack をUninstall実行
さぁ、これで何も気にすることなく思うままにテストができますね。 えっ?PowerShell Scriptでアンインストールしたい? んー、win32_productはアクセスが遅いので推奨できないんですが…これでどうぞ。
$program = Get-WmiObject win32_product -filter "name = 'PowerShellPack'"
$program.Uninstall()

WPKでWPFする

インストールされるモジュールからわかる通り、WPKはWPFに用いずとも便利なモジュール(コマンドレット)として動作します。 今回は、WPFでの利用に主眼を置きますので割愛しますが、機会があれば…。

MSDNのコードサンプル

WPKでWPFについては、インストールされるモジュールパスにあるWriting User Interfaces with WPK.docxにも記載があります。 また、Doug Finke先生がWPKを用いたWPF利用例を以下のMSDNで詳しく紹介されています。
Windows PowerShell と WPF コードサンプルのダウンロード
では、さっそくWriting User Interfaces with WPK.docxを片手にちょこっと触ってみましょう。

WPKでWPFを実行前に

必ず、スクリプト頭などのWPKのコマンドレット実行前に以下の一文を入れてWPKモジュールをインポートしてください。 これで、Moduleパスから、WPKモジュールがスクリプトにインポートされます。
import-module WPK 

Hello World

おはよう世界ですねー。 New-Labelコマンドレットで表示名を指定して、-Showメソッドで表示するだけです!! 簡単w
New-Label “Hello, World” –Show
WPK_HelloWorld さて、WPFのメリットといえば……UI表示をプロパティで簡単に制御、かつ自動的にサイズも補正がかかることですねー。 では、-FontSizeパラメーターを指定して文字サイズを30に変えてみます。
New-Label “Hello, World” –Show -FontSize 30
WPK_FontSize さらに、-Background パラメータを指定して背景色をaquaにしてみます。
New-Label “Hello, World” –Show -FontSize 30 -Background aqua
WPK_Background そうそう、当然ですがIntelisenceも効きますw 私、インテリセンス無しでは生きていけません。 WPK_Intelisence

WPKに何のモジュールがあるのかわからないよ

そんな時は、PowerShellerの頼れる味方、Get-Command先生の出番です。 ModuleにWPKを、Nameに探したいコマンドを入れればぱっと見つかります。
Get-Command -Name *button* -Module WPK
WPK_Get-Command

WPKで時計を表示してみよう

びっくりするぐらい簡単です。 たった5行です。
New-Label -FontSize 24 -On_Loaded {
    Register-PowerShellCommand -ScriptBlock { 
        $window.Content.Content = (Get-Date | Out-String).Trim()
    } -run -in "0:0:0.5"
} -show
どーん。 WPK_DigitalClock

ソースはどうなってるの

さて簡単ですが、基本的な内容は抑えられています。 1行目 : On_Loaded は、New-Labelコマンドレットが呼び出された時に、On_Loaded 以降の {} 内部のScriptBlockを実行する時に使います。
New-Label -FontSize 24 -On_Loaded { .. }
2行目 : Register-PowerShellCommand {} は、指定したコマンドを実行します。 今回は、-scriptBlock を指定しているので {} 内部に式を組み込めます。
    Register-PowerShellCommand -ScriptBlock {
3行目 : $window.Content.Content = (..) の$window.Contentで画面(ウィンドウ)での表示を指定し、..ContentでLabel内部のContentを指定しています。 今回は、代入内容にPowerShellコマンドレットである Get-Date を指定しています。 さらに Out-Stringに | (パイプ)で渡して、.Trim()メソッドで余計な空白を消しています。
        $window.Content.Content = (Get-Date | Out-String).Trim()
※Labelについて詳しくは、MDSNを参照してください。
Label クラス
4行目 : } でRegister-PowerShellCommand -ScriptBlock { } を閉じています。 そして、-run -in "0:0:0.5" で、0.5秒ごとに再実行して現在時刻を表示しています。
    } -run -in "0:0:0.5"
5行目 : } でOn_Loaded { } を閉じています。 そして -Show でWPFで描画しています。← 重要w -Showを忘れるとWPF描画されずに終わります。
} -show

まとめ

そろそろ飽きたのでWPKは終わります(爆) ご存じのとおり、CUIでは自分でScriptBlockなどで定義したProperty表示内容を自在に表示するために、New-Object -NotePropertyをいじるなどの手間が必要になったりします。 その点も、WPKでWPFで描画すればユーザー視点では見やすいですね。 ただしCUIの最大のメリットはバッチジョブ、バックグランドジョブだと思ってるので、そういう意味ではGUIは目的が違いますね。 要は、用途に応じて使い分けよう!!ということで。 少しでも検討になれば幸いです……が、次回のWPF紹介記事であるShow-UIは、WPK + PowerBootsというお題目のWPK発展版なので……(おい