ParameterSet не работает в настраиваемом командлете PowerShell на C #

У меня есть следующий код, в котором я пытаюсь создать собственный командлет для PowerShell с помощью C #.

Что я хочу сделать с моим настраиваемым командлетом, так это то, что пользователь должен вызвать его с двумя параметрами, из которых первый должен быть -Text или -File или -Dir, а следующий должен быть значением, строкой, которая определяет значение для текста, файла или каталога.

Дело в том, что если я попытаюсь вызвать свой командлет, например, с параметром -Test, который, конечно, является неправильным параметром, я не получу значение оператора по умолчанию, в котором говорится: «Неверное имя параметра» < / сильный>.

Думаю, мой код просто не дойдет до той части переключателя, которая используется по умолчанию.

Кстати, 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
    }
}

person Community    schedule 05.05.2013    source источник
comment
Достигает ли вообще ProcessRecord? Если да, уверены ли вы, что ни один из случаев, связанных с переключением, не выполняется? Потому что вы говорите, что компилятор C # сломан. И я очень сомневаюсь, что в этом проблема. PS: Как насчет того, чтобы упростить использование CmdLet, определив набор параметров по умолчанию? [Командлет (VerbsCommon.Get, SHA256, DefaultParameterSetName = Text)]   -  person Lars Truijens    schedule 05.05.2013


Ответы (2)


Поскольку PowerShell не имеет достаточно информации для «привязки» к параметрам, ProcessRecord вообще не вызывается, а вместо этого выдает ошибку. Таким образом, вы никогда не увидите, как срабатывает ваш переключатель.

Набор параметров не может быть разрешен с использованием указанных именованных параметров. + CategoryInfo: InvalidArgument: (:) [], ParameterBindingException + FullyQualifiedErrorId: AmbiguousParameterSet,

Вы даже не должны этого хотеть. Пусть PowerShell обработает параметры. Вы можете исправить свой CmdLet, выполнив следующие действия:

  1. Удалите Position = 0 для SwitchParameters. Наличие позиционных SwitchParameters не логично. PowerShell может легко определять SwitchParameters в любом положении
  2. Не делайте SwitchParameters обязательными. Это бесполезно. Переключатель либо есть, либо нет, правда или ложь. Заставлять его быть там не имеет смысла. Это все равно что заставить это быть правдой.
  3. Дайте своему CmdLet DefaultParameterSetName. Логично было бы выбрать один из определенных наборов параметров, например «Текст».
  4. Сделайте свой параметр аргумента 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. Вернитесь к своему умолчанию.

person Lars Truijens    schedule 06.05.2013

Ларс прав. Связывание параметров - это отдельная процедура, внешняя по отношению к вашему командлету. Если синтаксис неверен, командлет даже не выполняется.

person x0n    schedule 05.05.2013
comment
Дело в том, что если я вызываю свою функцию, например: Get-SHA256 -Text Some text here., Она работает нормально, также использование параметров -File или -Dir дает хорошие результаты. Если я не напишу первый или второй аргумент или напишу что-то другое, например, -Test, скажем так, это, конечно, не сработает. Но я не могу найти сообщение об ошибке: где-то отображается неверное имя параметра. - person ; 06.05.2013
comment
@erkant - вы не увидите это сообщение об ошибке. Вы совершенно не понимаете, о чем мы говорим. Ваш командлет НЕ проверяет параметры. Powershell проверяет их перед запуском вашего командлета. Он считывает метаданные из команды. Команда никогда не запускается, если параметры недействительны, поэтому вы НИКОГДА не увидите свое сообщение. - person x0n; 07.05.2013