tech.guitarrapc.cóm

Technical updates

PowerShellでWPFしたい Part1 - WPK編

前回の予告通り、今回はPowerShellでWPFに関する記事です。 PowerShellは、ご存じの通り.NET Frameworkを基盤としたシェル環境です。シェル環境というとCUIだけと思いがちですがPowerShellは.NETの力を借りてGUI表示も出来るわけです。cmdの頃には考えられなかったですね。

PowerShellでGUIといえばWinFormsが今でも良く紹介されていますがWinFormsは嫌です。今回、WPF初学者の身ですが、PowerShellでWPFによるGUI表示をする手法とサンプル例の紹介です。

そもそもShellなのにGUI?

PowerShellでGUIをするメリットは、人によって色々あるでしょう。 私の場合は、以下がメリットに感じています。

  • PowerShellコマンドレットを、ソースで書けばそのままGUIに反映して利用できる
  • PowerShellのCUIに親しめないユーザーにもGUI表示することで親しみやすくできる
  • CUIに比べて、ユーザー視点では表示が見やすい人もいる

帝国兵様からも、このようなお言葉いただき安堵したのは内緒です。

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

一応確認です。PowerShell 2.0とv3.0で利用している.NET Framworkバージョンは以下です。

PowerShell 2.0 = .NET Framework = 2.0
PowerShell 3.0 = .NET Framework = 4.0

※.NET4.0かよ、という突っ込みは止めてあげましょう。 ※ 私の記事は、PowerShell 3.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を利用するには、以下の要件を満たす必要があります。

  • PowerShell 2.0以上 (ISE含む)
  • WPKのインストール(Import-Moduleコマンドレットで可能)
  • Set-Execution PolicyでRemoteSignedなど外部ps1スクリプトの読み込み許可

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

Windows 7/8、Windows Server 2008R2/2012をお使いの場合は、PowerShell 2.0が既にインストールされていますので、2と3のみ気にすればWPKは利用できます。 ただ、Windows Management Framework 3.0(WMF3.0)がリリースされていますので、PowerShell 3.0に上げられることを推奨はします。

Download Windows PowerShell

Windows Vista/2008の場合、PowerShell 1.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のもう1つの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で詳しく紹介されています。

では、さっそくWriting User Interfaces with WPK.docxを片手にちょこっと触ってみましょう。

WPKでWPFを実行前に

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

import-module WPK

Hello World

おはよう世界ですね。 New-Labelコマンドレットで表示名を指定して、-Showメソッドで表示するだけです!!

New-Label "Hello, World" –Show

さて、WPFのメリットといえば……UI表示をプロパティで簡単に制御、かつ自動的にサイズも補正がかかることですねー。 では-FontSizeパラメーターを指定して文字サイズを30に変えてみます。

New-Label "Hello, World" –Show -FontSize 30

さらに、-Backgroundパラメータを指定して背景色をaquaにしてみます。

New-Label "Hello, World" –Show -FontSize 30 -Background aqua

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

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

Get-Command -Name *button* -Module WPK

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

ソースはどうなってるの

さて簡単ですが、基本的な内容は抑えられています。 1行目 : On_Loadedは、New-Labelコマンドレットが呼び出された時に、On_Loaded以降のスクリプトブロックを実行する時に使います。

New-Label -FontSize 24 -On_Loaded { .. }

2行目

Register-PowerShellCommandは、指定したコマンドを実行します。 今回は、-scriptBlockを指定しているので {} 内部に式を組み込めます。

Register-PowerShellCommand -ScriptBlock {

3行目

$window.Content.Content = (..)$window.Contentで画面(ウィンドウ)での表示を指定し、..ContentLabel内部のContentを指定しています。 今回は、代入内容にPowerShellコマンドレットであるGet-Dateを指定しています。 さらにOut-String|(パイプ)で渡して.Trim()メソッドで余計な空白を消しています。

$window.Content.Content = (Get-Date | Out-String).Trim()

※Labelについて詳しくは、MDSNを参照してください。

Labelクラス.aspx)

4行目 :

}Register-PowerShellCommand -ScriptBlock { }を閉じています。-run -in "0:0:0.5"で、0.5秒ごとに再実行して現在時刻を表示しています。

} -run -in "0:0:0.5"

5行目 :

}On_Loaded { }を閉じています。 -ShowでWPF描画しています。← -Showを忘れるとWPF描画されずに終わります。

} -show

まとめ

そろそろ飽きたのでWPKは終わります。

ご存じのとおり、CUIでは自分でScriptBlockなどで定義したProperty表示内容を自在に表示するために、New-Object -NotePropertyをいじるなどの手間が必要になったりします。

その点も、WPKでWPF描画すればユーザー視点では見やすいですね。 ただしCUIの最大のメリットはバッチジョブ、バックグラウンドジョブだと思ってるので、そういう意味ではGUIは目的が違いますね。 要は、用途に応じて使い分けよう!!ということで。 少しでも検討になれば幸いです……が、次回のWPF紹介記事であるShow-UIは、WPK + PowerBootsというお題目のWPK発展版なので……