Skip to main content
 首页 » 编程设计

powershell之互斥的Powershell参数

2024年11月24日28shangdawei

场景

  • 我正在使用Visual Studio 2008和.NET 3.5为Powershell 2.0编写cmdlet
  • cmdlet需要3个参数。

  • cmdlet的预期语法如下所示:
    cmdletname [foo|bar] p1, p2 
    
  • 读取,因为用户必须为“-foo”或“-bar”提供一个值,但不能同时给出两者。

  • 有效输入示例
    cmdletname -foo xxx -p1 hello  -p2 world 
    cmdletname -bar yyy -p1 hello  -p2 world 
    

    无效输入示例
    cmdletname -foo xxx -bar yyy -p1 hello  -p2 world 
    

    我的问题
  • 我的问题是如何在powershell中执行此操作,以便它为我执行所有检查-或是否完全可能。
  • 我知道我可以仅对foo和bar使用两个可选参数,并且只需手动进行错误检查即可。这就是我目前实现的方式。
  • 另外,我对不同方法的建议感兴趣。
  • 请您参考如下方法:

    这是使用从PowerShell Community Extensions中的cmdlet提取的ParameterSetName的示例。顺便说一句,对于想法你可以browse the PSCX source code

    [Cmdlet(VerbsCommon.Set, PscxNouns.Clipboard,  
            DefaultParameterSetName = ParamSetText)] 
    [Description("Copies the item in the system clipboard.")] 
    [RelatedLink(typeof(GetClipboardCommand))] 
    [RelatedLink(typeof(OutClipboardCommand))] 
    [RelatedLink(typeof(WriteClipboardCommand))] 
    public class SetClipboardCommand : ClipboardCommandBase 
    { 
        ... fields elided 
     
        const string ParamSetRtf = "Rtf"; 
        const string ParamSetHtml = "Html"; 
        const string ParamSetText = "Text"; 
        const string ParamSetFiles = "Files"; 
        const string ParamSetImage = "Image"; 
        .  
        [AllowNull] 
        [Parameter(ValueFromPipeline = true, ParameterSetName = ParamSetImage)] 
        public Image Image { get; set; } 
        .  
        [AllowNull] 
        [AllowEmptyCollection] 
        [Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true, 
                   ParameterSetName = ParamSetFiles)] 
        public FileSystemInfo[] Files { get; set; } 
        .  
        [AllowNull] 
        [AllowEmptyString] 
        [Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true, 
                   ParameterSetName = ParamSetText)] 
        public string Text { get; set; } 
        .  
        [Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true, 
                   ParameterSetName = ParamSetHtml)] 
        public string Html { get; set; } 
        .          
        [Parameter(ValueFromPipeline = true, ValueFromRemainingArguments = true, 
                   ParameterSetName = ParamSetRtf)] 
        public string Rtf { get; set; } 
        .  
        protected override void ProcessRecord() 
        { 
            ... 
        } 
        . 
        protected override void EndProcessing() 
        { 
            ExecuteWrite(delegate 
            { 
                switch (ParameterSetName) 
                { 
                    case ParamSetFiles: 
                        if (Paths.Count == 0) 
                            WinFormsClipboard.Clear(); 
                        else 
                            WinFormsClipboard.SetFileDropList(_paths); 
                        break; 
     
                    case ParamSetImage: 
                        if (Image == null) 
                            WinFormsClipboard.Clear(); 
                        else 
                            WinFormsClipboard.SetImage(_image); 
                        break; 
     
                    case ParamSetRtf: 
                        SetTextContents(Rtf, TextDataFormat.Rtf); 
                        break; 
     
                    case ParamSetHtml: 
                        SetTextContents(Html, TextDataFormat.Html); 
                        break; 
     
                    default: 
                        SetTextContents(Text, TextDataFormat.UnicodeText); 
                        break; 
                } 
            }); 
        } 
        ... 
    } 
    

    请注意,该cmdlet通常声明一个默认的ParameterSetName,以帮助PowerShell确定存在歧义时使用的“默认”参数集。稍后,如果需要,您可以通过查询this.ParameterSetName来确定哪个参数集有效,就像上面EndProcessing()覆盖中的switch语句所做的那样。