2011/09/08
クリップボードアクセス完結編
PowerShellでクリップボードを読み書きする方法については5年ほど前にクリップボードアクセス(未完)II という記事を書きました。タイトル通り未完でして、このたび完結編を書こうと思いました。
System.Windows.Forms.Clipboardクラスを使う場合は先の記事にあるようにPowerShellをSTAで動作させる必要があります。ver.1の当時はその方法がありませんでしたが、ver.2ではpowershell.exeに-staパラメータが追加され、STAでの実行が可能となっています。
-staパラメータを使用しない場合は相変わらずこの方法は使えません。powershell.exe –staのプロセスを逐次起こして、クリップボードアクセス部分だけSTAの子プロセスでやらせることも不可能ではないですが、冗長ですしパフォーマンスの点で難があります。
ver.2ではAdd-Typeコマンドレットが追加され、任意のC#コードを動的に読み込むことができるようになりました。これを利用してクリップボードアクセスクラスを書くという手もあると思います。その中ではSTAのスレッドを起こしてクリップボードアクセスをすることになります。実際PowerShell Community Extensionsに含まれるOut-Clipboard/Get-Clipboardコマンドレットはそのような実装がされているようです。ですが動的にコードを読み込みコンパイルはやはりパフォーマンス上不利ですし、PSCXをインストールできない場合などもあるでしょう。
ところでSystem.Windows.Formsに含まれるTextBoxクラスはその名の通りテキストボックスコントロールなのですが、このコントロールにはCopy()メソッドとPaste()メソッドがあり、これらを使うとクリップボードに書き込み、クリップボードから読み込みが可能です。TextBoxクラスの良いところは、STAである必要がないところです。この方法を最初に提唱したのはこちらの方かな?
この方法を用いた関数もすでに公開されているのですが、PowerShellの作法に則った使い方ができるように少し改良を加えました。具体的には
Set-ClipBoard: 配列の指定、パイプラインからの入力を可能にした。
Get-ClipBoard: クリップボードの中身が複数行のテキストの場合、文字列配列を返すようにした。(Get-Contentと同様)
という変更を加えています。
function Set-ClipBoard { param([parameter(Mandatory=$true, ValueFromPipeline=$true)][object[]]$InputObject) begin { Add-Type -AssemblyName System.Windows.Forms $tb = New-Object System.Windows.Forms.TextBox $tb.Multiline = $true $out=@() } process { $out+=$InputObject } end { $tb.Text = $out -join "`r`n" $tb.SelectAll() $tb.Copy() } } function Get-ClipBoard { Add-Type -AssemblyName System.Windows.Forms $tb = New-Object System.Windows.Forms.TextBox $tb.Multiline = $true $tb.Paste() $tb.Text -replace "`r`n","`n" -replace "`r","`n" -split "`n" }
使い方例
# ファイルのフルパスをクリップボードに格納 Get-ChildItem|select -expand fullname|Set-ClipBoard # CSV文字列がクリップボードに入っている場合以下のコマンドを実行すると、 # クリップボードの中身が対応するHTML tableタグに置換される Get-ClipBoard|ConvertFrom-Csv|ConvertTo-Html -Fragment|Set-ClipBoard
やっぱりパイプで繋ぐのがPowerShellの醍醐味ですよね!
元記事:http://blogs.wankuma.com/mutaguchi/archive/2011/09/08/202547.aspxプライバシーポリシー