ここでは、各出力オブジェクトのデリゲートを呼び出して、出力をストリームするためにScriptBlockに拡張メソッドを追加するコードを示します。オブジェクトがコレクションにバックアップされないので、ストリーミングは真実です。これは、PowerShell 2.0以降用です。
public static class ScriptBlockStreamingExtensions {
public static void ForEachObject<T>(
this ScriptBlock script,
Action<T> action,
IDictionary parameters) {
using (var ps = PowerShell.Create()) {
ps.AddScript(script.ToString());
if (parameters != null) {
ps.AddParameters(parameters);
}
ps.Invoke(Enumerable.Empty<object>(), // input
new ForwardingNullList<T>(action)); // output
}
}
private class ForwardingNullList<T> : IList<T> {
private readonly Action<T> _elementAction;
internal ForwardingNullList(Action<T> elementAction) {
_elementAction = elementAction;
}
#region Implementation of IEnumerable
// members throw NotImplementedException
#endregion
#region Implementation of ICollection<T>
// other members throw NotImplementedException
public int Count {
get {
return 0;
}
}
#endregion
#region Implementation of IList<T>
// other members throw NotImplementedException
public void Insert(int index, T item) {
_elementAction(item);
}
#endregion
}
}
例:
// execute a scriptblock with parameters
ScriptBlock script = ScriptBlock.Create("param($x, $y); $x+$y");
script.ForEachObject<int>(Console.WriteLine,
new Dictionary<string,object> {{"x", 2},{"y", 3}});
(パラメータのサポートを2011年3月7日更新)このことができます
希望。
出典
2011-03-07 02:54:39
x0n
卑劣なことだ!私はそれが好きです。 – Josh
クールではありますが、必要なものではありません - 私はスクリプトブロックだけをテキストとしてではなく、ArgumentListを持つ実際のScriptBlockインスタンスとして必要としています。私が苦労していたArgumentListを握っています。結局私は単にInvoke-Commandをプログラム的に呼び出すことに頼らざるを得ませんでした。 – jkff
@jkff - APIでもっと時間を費やす必要があります - 私のコードは良いです。スクリプトブロックにパラメータ/引数を追加するには、AddArgument(位置指定)またはAddParameter(名前付き)を使用して追加する必要があります。コードサンプルを更新します。 – x0n