0

I have the following code, where I try to create a custom Cmdlet for PowerShell using C#.

What I want to do with my custom cmdlet is that, user should call it with two parameters, from which first one should be -Text or -File or -Dir, and the next one should be a value, a string which specifies the value for text, or file, or directory.

The point is that if I try to call my cmdlet with a parameter -Test for example, which is of course a wrong parameter, I don't get the value of the default statement, which says "Bad parameter name".

I guess my code just don't get till the default part of the switch.

By the way, SHA256Text, SHA256File, and SHA256Directory, are just custom helper methods that I have written, so don't worry about them.

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
    }
}
4

2 回答 2

2

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

于 2013-05-05T22:24:11.120 回答
2

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

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

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

  1. 移除 SwitchParameters 的 Position = 0。拥有位置 SwitchParameters 是不合逻辑的。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 一样调用。回退到您的默认值。

于 2013-05-06T21:02:08.467 回答