[在C#中创建PowerShell Cmdlet以便像这样使用它

问题描述 投票:3回答:2

我在C#中有一些类,我想在管道中使用它们,我已经看过有关它的文章,但是我还没有做到这一点。

[我现在正在使用它:

$suite = [MyProject.SuiteBuilder]::CreateSuite('my house')

$houseSet = $suite.AddSet('doors', 'These represents doors')
$houseSet.AddOption('blue', 'kitchen')
$houseSet.AddOption('black', 'bedreoom')
$houseSet.AddOption('white', 'toilet')

而且我希望能够在管道中像这样使用它:

$suite = [MyProject.SuiteBuilder]::CreateSuite('my house')

$suite | AddSet('doors', 'These represents doors') `
       | AddOption('blue', 'kitchen') `
       | AddOption('black', 'bedreoom') `
       | AddOption('white', 'toilet')

这是我的C#类:

//SuiteBuilder.cs
public static class SuiteBuilder
{
    public static Suite CreateTestSuite(string name)
    {
        return new Suite(name);
    }
}

//Suite.cs
public class Suite : PSCmdlet
{
    public string Name { get; set; }
    public IEnumerable<Set> Sets { get; set; }

    public Suite(string name)
    {
        Name = name;
        Sets = new List<Set>();
    }

    // call this method in pipeline
    public Set AddSet(string type, string description)
    {
        Sets.Add(new Set(type, description));
        return Sets.Last();
    }
}


//Set.cs
public class Set : PSCmdlet
{
    public string Type { get; set; }
    public string Description { get; set; }
    public IEnumerable<Option> Options { get; set; }

    public Set(string type, string description)
    {
        Type = type;
        Description = description;
        Options = new List<Option>();
    }

    // call this method from pipeline
    public Set AddOption(string color, string place)
    {
        Options.Add(new Option(color, place));
        return this;
    }
}


//option.cs
public class Option : PSCmdlet
{
    public string Color { get; set; }
    public string Place { get; set; }

    public Option(string color, string place)
    {
        Color = color;
        Place = place;
    }
}

而且我正在努力使这些函数可用于管道形式中的调用。

我还需要在每个要调用的评论之前添加一个像call this method in pipeline之类的评论。

c# powershell
2个回答
0
投票

您可以使用ValueFromPipeline = $ true。但是,如果要继续执行管道操作,则必须引用类型变量,并返回该项目。我不知道解决此问题的方法。由于它会返回,因此您必须在末尾添加Out-Null以防止它击中控制台。

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-6

function Add-Option {
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [ref]$Item,
        [Parameter(Mandatory = $true, Position = 0)]
        [String]$Color
        [Parameter(Mandatory = $true, Position = 1)]
        [String]$Room
    )
    $Item.Value.AddOption($Color,$Room)
    return $Item
}

$suite = [MyProject.SuiteBuilder]::CreateSuite('my house')

[ref]$suite | Add-Option 'blue' 'kitchen' `
            | Add-Option 'black' 'bedroom' `
            | Out-Null


0
投票

要在C#中创建Powershell Cmdlet,请按照以下步骤操作:

  1. 创建C#类库项目(例如,将其命名为MyCmdlets
  2. 安装软件包Microsoft.PowerShell.5.ReferenceAssemblies
  3. 独立于PowerShell创建模型类。 (请参阅文章底部的代码)
  4. 考虑以下注意事项创建cmdlet :(请参阅文章底部的代码)

    • 每个cmdlet,创建一个C#类
    • CmdLet类派生
    • Cmdlet属性装饰类,指定动词和动词后的名称,例如,如果您想拥有Add-Set,请使用[Cmdlet(VerbsCommon.Add, "Set")]
    • [如果要为管道提供输出,请使用指定输出类型的OutputType属性修饰类,例如,如果要为管道提供Set类型的输出,请使用[OutputType(typeof(Set))]。] >
    • 根据您的cmdlet的每个输入参数,定义一个C#属性。
    • 通过Parameter属性装饰每个参数属性。
    • 如果要从管道接受参数,则使用Parameter属性进行修饰时,例如,将ValueFromPipeline设置为true,例如[Parameter(ValueFromPipeline =true)
  5. 构建项目。

  6. 打开PowerShell ISE并运行以下代码:

  7. Import-Module "PATH TO YOUR BIN DEBUG FOLDER\MyCmdlets.dll"
    $suite = [MyCmdLets.Suite]::New("suite1")
    $suite | Add-Set -Type "type1" -Description "desc1"`
           | Add-Option -Color "color1" -Place "place1"`
           | Add-Option -Color "color2" -Place "place2" | Out-Null
    
    $suite | Format-Table
    $suite.Sets[0] | Format-Table
    $suite.Sets[0].Options | Format-Table
    

    您将收到以下输出:

    Name   Sets           
    ----   ----           
    suite1 {MyCmdlets.Set}
    
    
    Type  Description Options                             
    ----  ----------- -------                             
    type1 desc1       {MyCmdlets.Option, MyCmdlets.Option}
    
    
    Color  Place 
    -----  ----- 
    color1 place1
    color2 place2
    

    模型类

像这样设计独立于PowerShell的模型类:

using System.Collections.Generic;
namespace MyCmdlets
{
    public class Suite
    {
        public string Name { get; set; }
        public List<Set> Sets { get; } = new List<Set>();
        public Suite(string name) {
            Name = name;
        }
    }
    public class Set
    {
        public string Type { get; set; }
        public string Description { get; set; }
        public List<Option> Options { get; } = new List<Option>();
        public Set(string type, string description) {
            Type = type;
            Description = description;
        }
    }
    public class Option 
    {
        public string Color { get; set; }
        public string Place { get; set; }
        public Option(string color, string place) {
            Color = color;
            Place = place;
        }
    }
}

CmdLet类

根据我上面描述的注释设计cmdlet类:

using System.Management.Automation;
namespace MyCmdlets  
{
    [Cmdlet(VerbsCommon.Add, "Set"), OutputType(typeof(Set))]
    public class AddSetCmdlet : PSCmdlet 
    {
        [Parameter(ValueFromPipeline = true), ValidateNotNull]
        public Suite Suite { get; set; }
        [Parameter]
        public string Type { get; set; }
        [Parameter]
        public string Description { get; set; }
        protected override void ProcessRecord() {
            var set = new Set(Type, Description);
            Suite.Sets.Add(set);
            WriteObject(set);
        }
    }

    [Cmdlet(VerbsCommon.Add, "Option"), OutputType(typeof(Option))]
    public class AddOptionCmdlet : PSCmdlet 
    {
        [Parameter(ValueFromPipeline = true), ValidateNotNull]
        public Set Set { get; set; }
        [Parameter]
        public string Color { get; set; }
        [Parameter]
        public string Place { get; set; }
        protected override void ProcessRecord() {
            var option = new Option(Color, Place);
            Set.Options.Add(option);
            WriteObject(Set);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.