C# でバイナリ Powershell モジュールを作成しています。動的な実行時のタブ補完を提供するパラメーターを含むコマンドレットが必要です。ただし、バイナリモジュールでこれを行う方法を理解するのに苦労しています。これを機能させるための私の試みは次のとおりです。
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
namespace DynamicParameterCmdlet
{
[Cmdlet("Say", "Hello")]
public class MyCmdlet : PSCmdlet
{
[Parameter, PSTypeName("string")]
public RuntimeDefinedParameter Name { get; set; }
public MyCmdlet() : base() {
Collection<Attribute> attributes = new Collection<Attribute>() {
new ParameterAttribute()
};
string[] allowedNames = NameProvider.GetAllowedNames();
attributes.Add(new ValidateSetAttribute(allowedNames));
Name = new RuntimeDefinedParameter("Name", typeof(string), attributes);
}
protected override void ProcessRecord()
{
string name = (string)Name.Value;
WriteObject($"Hello, {Name}");
}
}
public static class NameProvider
{
public static string[] GetAllowedNames()
{
// Hard-coded array here for simplicity but imagine in reality this
// would vary at run-time
return new string[] { "Alice", "Bob", "Charlie" };
}
}
}
これはうまくいきません。タブ補完機能がありません。エラーも表示されます:
PS > Say-Hello -Name Alice
Say-Hello : Cannot bind parameter 'Name'. Cannot convert the "Alice" value of type "System.String" to type "System.Management.Automation.RuntimeDefinedParameter".
At line:1 char:17
+ Say-Hello -Name Alice
+ ~~~~~
+ CategoryInfo : InvalidArgument: (:) [Say-Hello], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,DynamicParameterCmdlet.MyCmdlet
非バイナリ Powershell モジュールでそれを行う方法の例を含む記事を見つけました。インクルードする非バイナリ モジュールの後に、オブジェクトDynamicParam
を構築して返すステートメントが続くようです。この例に基づいて、オーバーライド可能なメソッドがあるのと同じように、おそらくオーバーライド可能なメソッドまたはRuntimeParameterDictionary
類似のクラスで同等のものを期待します。PSCmdlet
GetDynamicParameters()
BeginProcessing()
このままでは、バイナリ モジュールは Powershell の世界では二流の市民になりそうです。確かに私が見逃したこれを行う方法はありますか?