カテゴリー別アーカイブ: Powershell

ジェネリック、Private、Protectedメソッドを実行する

「プライベートメンバにアクセスする」で、プライベートなメソッドを実行する Invoke-PrivateMethod をご紹介しました。
今回のスクリプトは、それの発展系で、ジェネリックメソッドに対応したものです。
一般の使用においては、プライベートメソッドの実行よりもジェネリックメソッドの実行に使われる方が多いのではないかと思い、スクリプト名を変更しています。

用例1

(1).ToString(‘D4’) と等価です。

PS> Invoke-Method (1) ToString('D4')
0001

用例2

Array.ForEach を呼び出します。

PS> $delegate = New-Delegate Action[int] {Write-Host ($args[0] * $args[0])}
PS> Invoke-Method ([Array]) ForEach([int[]](1..5), $delegate) -GenericType int
1
4
9
16
25

用例3

System.Linq.Enumerable の Repeat メソッドを呼び出します。ジェネリック型が System.Object の場合、-GenericType を省略できます。

PS> Invoke-Method ([Linq.Enumerable]) Repeat('Hello', 3)
Hello
Hello
Hello

ダウンロード

テキストエンコーディング(3)

Resolve-Encoding.ps1 の改修

  • BOM 付き UTF8 に対応しました。

Convert-Encoding.ps1 の改修

  • パラメータに以下のエイリアスを作成しました。

    • LiteralPath = IL
    • OutputLiteralPath = OL
    • InputByte = IB
    • InputString = IS
    • InputEncoding = IE
    • OutputEncoding = OE
  • 入力の数に関わらず、BOM の出力を一回だけにしました。
  • 入力に BOM が含まれていた場合、BOM を出力しないようにしました。
  • InputString の値として $null を許可しました。
  • パイプラインから文字列が入力された時、InputString として受け取るようにしました。
  • InputString の最後に改行を入れていたのを廃止しました。
  • その他細かな修正

ダウンロード

テキストエンコーディングの変換

Convert-Encoding.ps1 は、文字列エンコーディングを自動判別して内容を出力したり、特定のエンコードでテキストファイルに書き込むスクリプトです。

-InputEncoding を指定しなかった場合、入力エンコーディングを自動判別します。また、-OutputEncoding を指定しなかった場合、[String] として出力します。

-InputEncoding および -OutputEncoding の指定は、[System.Text.Encoding] オブジェクト、コードページ、エンコーディング名の三種類が使用可能です。また、Out-File などで用いられる「UTF8, Default, Unicode…」などの表記も可能です。詳細は Get-Help Convert-Encoding をご覧ください。

用例

用例1: 文字列を EUC-JP で .euc.txt に書き込み、その内容を表示します。

PS> Convert-Encoding -InputString サンプルテキスト euc-jp .euc.txt
PS> Resolve-Encoding .euc.txt

BodyName : euc-jp
EncodingName : 日本語 (EUC)
HeaderName : euc-jp
WebName : euc-jp
WindowsCodePage : 932
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.InternalEncoderBestFitFallback
DecoderFallback : System.Text.InternalDecoderBestFitFallback
IsReadOnly : True
CodePage : 51932

PS> Get-Content .euc.txt
・オ・ラ・・ニ・ュ・ケ・ネ
PS> Convert-Encoding .euc.txt -InputEncoding euc-jp
サンプルテキスト

用例2: .euc.txt のエンコードを自動判別して内容を表示します。(Resolve-Encoding.ps1 が必要)

PS> Convert-Encoding .euc.txt
サンプルテキスト

追記

2012年11月20日改良版が存在します。そちらをお使いください。

テキストエンコーディングの自動解析(2)

前回(テキストエンコーディングの自動解析)ご紹介したスクリプトを改良しました。

変更点は、-LiteralPath に対応したことと、複数のファイル名を扱えるようになったことです。

その他、細かなバグを修正しました。

追記

2012年11月20日、改良版が存在します。そちらをお使いください。

テキストエンコーディングの自動解析

指定したファイルまたは入力のテキストエンコーディングを解析して出力します。

対応するエンコーディングは、UTF32 UTF32BE UTF16(Unicode) UTF16BE UTF8 JIS(ISO-2022-JP) EUC-JP Shift-JIS ASCII です。

UTF32 UTF32BE UTF16 UTF16BE については、BOM 付きのもののみ対応しています。UTF8 は BOM が無くても解析可能です。

用例

用例1: ファイルのエンコーディングを求める

PS> Resolve-Encoding sample.txt | Select-Object EncodingName

EncodingName
———-
日本語 (EUC)

用例2: 入力のエンコーディングを求める

PS> Get-Content sample.txt -Encoding Byte | Resolve-Encoding | Select-Object EncodingName

EncodingName
———-
日本語 (EUC)

詳しくは Get-Help Resolve-Encoding をご覧ください。

実装

各エンコーディングに対し、入力されたデータが「そのエンコーディングである(成功)」「そのエンコーディングではない(失敗)」「まだわからない(解析中)」の三種類で判定するオートマトンをそれぞれ作成しし、1 バイトずつ順に入力していきます。

最初にどれか一つのオートマトンが成功状態になれば、以降の入力をキャンセルし、成功したオートマトンのエンコーディングを出力します。

失敗したオートマトンはリストから削除し、以降入力を与えません。

入力が終了した時、残ったオートマトンの中で最も優先順位の高いものを出力します。

「高度な関数」(Get-Help about_functions_advanced)を使用していますので、PowerShell 2.0 以上でないと動作しません。

追記

2012年11月20日 (改良版)が存在します。そちらをお使いください。

コマンドバッファスタック

概要

Zsh というシェルには、コマンドバッファスタック(コマンドラインスタック)と呼ばれる機能があります。何かコマンドを打っている途中で他の作業がしたくなった時、今まで打ったものを一時的に退避させておき、後で再利用する機能です。次のスクリプトは、PowerShell でコマンドバッファスタックを実装するものです。

続きを読む

Windows PowerShell Get-Enjoy コンテスト

昨年末、マイクロソフト主催の「Windows PowerShell Get-Enjoy コンテスト」というコンテストにスクリプトを応募しました。「Windows PowerShell」の名を冠しながら「Windows PowerShell で作成されたスクリプトである必要はありません。」と銘打たれている変わったコンテストでしたが、評価が不当に低い気がする PowerShell が、このようなイベントを通じて認知されていけば嬉しいことです。便利な PowerShell ですが、今よりユーザーが増えればもっともっと便利になるでしょう。

応募したスクリプトは、「Windows PowerShell で delegate」で掲載したスクリプト「New-Delegate.ps1」です。ありがたいことに吉岡洋様より選考委員特別賞をいただきました。賞品のデジタルビデオが届くのを楽しみに待っています。

新しいクラスを作る(7) ― PInvoke

概要

New-Class.ps1 を使い、PowerShell から Win32API を呼び出します。

用例

Beep 関数を使って音を鳴らします。

PS> New-Class Class11 {

>>     PInvokeMethod public, static stdcall bool kernel32.dll Beep([UInt32], [UInt32])

>> }

>>

 

PS> [Class11]::Beep(262, 500)

方法

PInvokeMethod は次のように指定します。

PInvokeMethod <属性> <呼び出し規約> <戻り値の型> <ライブラリ名> <メソッド名> <パラメータ型リスト> <キャラクタセット> <エントリ名>

<属性> には、static を含める必要があります。Win32API はオブジェクトインスタンスを受け取らないからです。

<呼び出し規約> は、ほとんどの場合 stdcall で構いません。特に指定のある場合は変更してください。

<ライブラリ名> には、その API 関数が収められているダイナミックリンクライブラリを指定します。

<メソッド名> は、通常、その API 関数と同じものを使ってください。もし別の名前を使いたい場合には、<エントリ名> に API 関数の名前を指定してください。

<キャラクタセット> は、auto, ansi, unicode から選択してください。デフォルトは auto です。