c# - Powershell 二进制模块 : Dynamic tab completion for Cmdlet parameter values

标签 c# powershell powershell-module

我正在用 C# 编写一个二进制 Powershell 模块,我希望有一个带有参数的 Cmdlet,该参数提供动态的运行时选项卡完成功能。但是,我正在努力弄清楚如何在二进制模块中执行此操作。这是我尝试让它工作的尝试:

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

我找到了 an article以及如何在非二进制 Powershell 模块中执行此操作的示例。在非二进制模块中,您似乎包含 DynamicParam,后跟构建和返回 RuntimeParameterDictionary 对象的语句。基于这个例子,我期望 PSCmdlet 类中的等价物,也许是可重写的 GetDynamicParameters() 方法或类似的东西,就像有一个可重写的 BeginProcessing () 方法。

按照这种速度,二进制模块正在成为 Powershell 世界中的二等公民。当然有一种我错过的方法可以做到这一点?

最佳答案

这是一种在 PowerShell v5 中实现自定义参数完成器的方法:

Add-Type @‘
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Management.Automation;
    using System.Management.Automation.Language;
    [Cmdlet(VerbsDiagnostic.Test,"Completion")]
    public class TestCompletionCmdlet : PSCmdlet {
        private string name;
        [Parameter,ArgumentCompleter(typeof(NameCompleter))]
        public string Name {
            set {
                name=value;
            }
        }
        protected override void BeginProcessing() {
            WriteObject(string.Format("Hello, {0}", name));
        }
        private class NameCompleter : IArgumentCompleter {
            IEnumerable<CompletionResult> IArgumentCompleter.CompleteArgument(string commandName,
                                                                              string parameterName,
                                                                              string wordToComplete,
                                                                              CommandAst commandAst,
                                                                              IDictionary fakeBoundParameters) {
                return GetAllowedNames().
                       Where(new WildcardPattern(wordToComplete+"*",WildcardOptions.IgnoreCase).IsMatch).
                       Select(s => new CompletionResult(s));
            }
            private static string[] GetAllowedNames() {
                return new string[] { "Alice", "Bob", "Charlie" };
            }
        }
    }
’@ -PassThru|Select-Object -First 1 -ExpandProperty Assembly|Import-Module

特别是,您需要:

  • 实现IArgumentCompleter接口(interface)。实现此接口(interface)的类应具有公共(public)默认构造函数。
  • ArgumentCompleterAttribute 属性应用于字段的属性,用作cmdlet 参数。作为属性的参数,您应该传递 IArgumentCompleter 实现。
  • IArgumentCompleter.CompleteArgument 中,您有 wordToComplete 参数,因此您可以按用户已输入的文本过滤完成选项。

尝试一下:

Test-Completion -Name Tab

关于c# - Powershell 二进制模块 : Dynamic tab completion for Cmdlet parameter values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33132028/

相关文章:

node.js - Windows : Install node and then in same . ps1 脚本 npm 包出现错误 "npm"无法识别

Powershell Dynamics CRM,如何向用户添加两个队列

powershell - 如何从二进制 cmdlet 调用脚本模块 cmdlet?

c# - 是否有任何适用于 ASP.NET MVC 应用程序的开源 Comet Web 服务器?

azure - 无法识别“New-AzSqlServerFirewallRule” - Azure Dev Ops Pipeline 的 Azure PowerShell 问题

c# - 新的 MVC View ,每次都会出现 404,即使使用正确的 Controller

powershell - VS Code - Powershell 模块 - 命令无法识别

powershell - 如何解决 PowerShell V5 中的模块嵌套限制已超出错误?

c# - 在 C# 中,将方法包含在此类中的目的是什么?

c# - 列出 CHM 文件中的所有主题