【问题标题】:ParameterSet doesn't work in custom PowerShell cmdlet in C#ParameterSet 在 C# 中的自定义 PowerShell cmdlet 中不起作用
【发布时间】:2013-05-07 05:02:08
【问题描述】:

我有以下代码,我尝试使用 C# 为 PowerShell 创建自定义 Cmdlet。

我想用我的自定义 cmdlet 做的是,用户应该使用两个参数调用它,第一个参数应该是 -Text 或 -File 或 -Dir,下一个应该是一个值,一个字符串指定文本、文件或目录的值。

关键是,如果我尝试使用参数 -Test 调用我的 cmdlet,例如,这当然是一个错误的参数,我不会得到默认语句的值,即 "Bad parameter名字”

我猜我的代码直到开关的默认部分才得到。

顺便说一下,SHA256Text、SHA256File 和 SHA256Directory 只是我写的自定义辅助方法,所以不用担心。

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Management.Automation;

namespace PSSL
{
    [Cmdlet(VerbsCommon.Get, "SHA256")]
    public class GetSHA256 : PSCmdlet
    {
        #region Members

        private bool text;
        private bool file;
        private bool directory;
        private string argument;

        #endregion

        #region Parameters

        [Parameter(Mandatory = true, Position = 0, ParameterSetName = "Text")]
        public SwitchParameter Text
        {
            get { return text; }
            set { text = value; }
        }

        [Parameter(Mandatory = true, Position = 0, ParameterSetName = "File")]
        public SwitchParameter File
        {
            get { return file; }
            set { file = value; }
        }

        [Parameter(Mandatory = true, Position = 0, ParameterSetName = "Directory")]
        public SwitchParameter Dir
        {
            get { return directory; }
            set { directory = value; }
        }

        [Parameter(Mandatory = true, Position = 1)]
        [ValidateNotNullOrEmpty]
        public string Argument
        {
            get { return argument; }
            set { argument = value; }
        }

        #endregion

        #region Override Methods

        protected override void ProcessRecord()
        {
            switch(ParameterSetName)
            {
                case "Text":
                    SHA256Text(argument);
                    break;

                case "File":
                    SHA256File(argument);
                    break;

                case "Directory":
                    SHA256Directory(argument);
                    break;

                default:
                    throw new ArgumentException("Error: Bad parameter name.");
            }
        }

        #endregion
    }
}

【问题讨论】:

  • 它是否达到了 ProcessRecord?如果是这样,您确定没有任何来自交换机的案例被执行吗?因为你让它听起来 C# 编译器坏了。我非常怀疑这是问题所在。 PS:如何通过定义默认参数集来更轻松地使用 CmdLet? [Cmdlet(VerbsCommon.Get, "SHA256", DefaultParameterSetName = "Text")]

标签: c# powershell parameters switch-statement powershell-cmdlet


【解决方案1】:

由于 PowerShell 没有足够的信息来“绑定”参数,因此根本不会调用 ProcessRecord,而是会给出错误。所以你永远不会看到你的开关被执行。

无法使用指定的命名参数解析参数集。 + CategoryInfo : InvalidArgument: (:) [], ParameterBindingException + FullyQualifiedErrorId : AmbiguousParameterSet,

你甚至不应该想要。让 PowerShell 处理参数。您可以通过执行以下操作来修复您的 CmdLet:

  1. 移除 SwitchParameters 的 Position = 0。这不合逻辑 有位置开关参数。 PowerShell 可以在任何位置轻松检测 SwitchParameters
  2. 不要强制 SwitchParameters。这是没有用的。开关存在与否,真或假。强迫它在那里是没有意义的。这就像强迫它成为真实的一样。
  3. 给你的 CmdLet 一个 DefaultParameterSetName。合乎逻辑的是选择定义的参数集之一,例如“文本”
  4. 让您的 Argument 参数 Position = 0。因为 SwitchParameters 不需要位置,所以这是第一个。

现在你可以这样称呼它:

Get-SHA256 'SomeText'
Get-SHA256 'SomeText' -Text
Get-SHA256 -Text 'SomeText'
Get-SHA256 'C:\Some.File' -File
Get-SHA256 -File 'C:\Some.File'
etc

还可以考虑检查 SwitchParameters 值,而不是打开 ParameterSetName。 SwithParameters 可以像 -File:$false 一样调用。回退到您的默认设置。

【讨论】:

    【解决方案2】:

    拉斯是正确的。参数绑定器是 cmdlet 外部的单独过程。如果语法不正确,甚至不会执行 cmdlet。

    【讨论】:

    • 重点是,如果我调用我的函数,例如:Get-SHA256 -Text "Some text here.",它工作得很好,也使用 -File 或 -Dir 选项产生良好的结果。如果我不写第一个或第二个参数,或者写其他东西,比如 -Test 假设,它当然不起作用。但我似乎找不到错误消息:错误的参数名称显示在某处。
    • @erkant - 您不会看到该错误消息。你根本不明白我们在说什么。您的 cmdlet 不是验证参数的东西。 Powershell 在运行 cmdlet 之前会对其进行验证。它从命令中读取元数据。如果参数无效,该命令将永远不会运行,因此您将永远不会看到您的消息。
    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 2012-12-28
    • 1970-01-01
    • 2013-04-26
    • 2019-08-16
    • 2012-09-22
    • 2013-03-16
    • 1970-01-01
    相关资源
    最近更新 更多