2011/05/04

PSプロバイダをC#で実装する場合、NavigationCmdletProviderクラスなんかを継承させたクラスを作ってCmdletProvider属性をつけてやりますが、今回はその辺の話は省略して、このクラスからPowerShell変数を読み書きする方法について述べます。

たとえばそのPSプロバイダを含むモジュールを読み込んだPowerShellコンソールに変数$valを書き出すには、

this.SessionState.PSVariable.Set("val", 1);

のようにします。

逆にコンソールで読み込まれている変数$valの値を読み込むには、

PSVariable ret = this.SessionState.PSVariable.Get("val");

のようにします。

と、それだけなら話は簡単なのですが、実はPowerShellの仕組み上、そう単純には行きません。書き出しの方はさほど問題はないのですが、問題は読み込み。ここでretに格納されたオブジェクトから$valの実際の値を取得するにはどうすればいいでしょうか。

このコードを上から順に実行したら、ret.Valueにその値が入っているので、これを単にintにキャストすればOKです。

しかし$valがPowerShell側でその値が変更されていた場合は、ret.ValueにはPSObjectという、元の値をラッピングしたオブジェクトが格納されています。実際の値はPSObject.BaseObjectに格納されています。よって、(int)((PSObject)ret.Value).BaseObjectのように取得する必要があります。

めんどくさいのでメソッドにしてしまいました。

private T GetPSVariableValue<T>(string name)
{
    PSVariable variable = this.SessionState.PSVariable.Get(name);
    if (variable != null)
    {
        T obj;
        if (variable.Value is PSObject)
        {
            obj = (T)((PSObject)variable.Value).BaseObject;
        }
        else
        {
            obj = (T)variable.Value;
        }
        return obj;
    }
    else
    {
        return default(T);
    }
}

使い方は

int ret = GetPSVariableValue<int>("val");

みたいな感じです。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2011/05/04/198782.aspx

古い記事へ | 新しい記事へ


プライバシーポリシー

Twitter

Books