在C#管道链接中创建PowerShell cmdlet
我有一些C#中的类,我想在管道中使用它们,我看过关于它的文章,但我还没有能够做到这一点 下面是我现在使用它的方式:在C#管道链接中创建PowerShell cmdlet,c#,powershell,cmdlet,C#,Powershell,Cmdlet,我有一些C#中的类,我想在管道中使用它们,我看过关于它的文章,但我还没有能够做到这一点 下面是我现在使用它的方式: $suite = [MyProject.SuiteBuilder]::CreateSuite('my house') $houseSet = $suite.AddSet('doors', 'These represents doors') $houseSet.AddOption('blue', 'kitchen') $houseSet.AddOption('black', 'be
$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
公共静态类SuiteBuilder
{
公共静态套件CreateTestSuite(字符串名称)
{
返回新套房(姓名);
}
}
//Suite.cs
公共类套件:PSCmdlet
{
公共字符串名称{get;set;}
公共IEnumerable集合{get;set;}
公共套件(字符串名称)
{
名称=名称;
集合=新列表();
}
//在管道中调用此方法
公共集AddSet(字符串类型、字符串描述)
{
添加(新集合(类型、说明));
返回集合.Last();
}
}
//Set.cs
公共类集:PSCmdlet
{
公共字符串类型{get;set;}
公共字符串说明{get;set;}
公共IEnumerable选项{get;set;}
公共集(字符串类型、字符串描述)
{
类型=类型;
描述=描述;
选项=新列表();
}
//从管道调用此方法
公共设置添加选项(字符串颜色、字符串位置)
{
选项。添加(新选项(颜色、位置));
归还这个;
}
}
//option.cs
公共类选项:PSCmdlet
{
公共字符串颜色{get;set;}
公共字符串Place{get;set;}
公共选项(字符串颜色、字符串位置)
{
颜色=颜色;
地点=地点;
}
}
我正在努力使这些函数能够以管道形式调用
在我需要调用的每个注释之前,我还添加了一条注释,如
在管道中调用此方法。您可以使用valuefrompipline=$true。但是,如果要继续管道,则必须引用类型变量并返回项。我不知道如何解决这个问题。由于它将返回,您必须在末尾添加一个Out Null
,以防止它击中控制台
简而言之,您需要:
- 使用
[参数(ValueFromPipeline=true)]从管道接受参数
- 通过调用process方法中的
WriteObject
方法向管道提供输出
详细的逐步回答
在这篇文章中,我将对您的代码进行一点重构,并向您展示如何在C#中创建,以及如何定义参数,从管道中接受参数,以及向管道提供输出。然后你可以很容易地写下如下内容:
$suite=[mycmdlet.suite]::新建(“suite1”)
$suite |添加设置“类型1”“说明1”`
|添加选项“color1”“place1”`
|添加选项“color2”“place2”| Out Null
为此,请执行以下步骤:
创建一个C#类库项目(例如,命名它mycmdlet
)
安装软件包
创建独立于PowerShell的模型类。(见帖子底部的代码)
创建cmdlet时请考虑以下注意事项:(请参阅文章底部的代码)
- 根据每个cmdlet,创建一个C#类
- 源于类
- 使用指定动词和动词后的名称的属性来修饰类,例如,如果您希望使用
添加集
,请使用[Cmdlet(VerbsCommon.Add,“Set”)]
- 如果希望管道具有输出,请使用指定输出类型的属性装饰该类,例如,如果希望管道具有
Set
类型的输出,请使用[OutputType(typeof(Set))]
- 根据cmdlet的每个输入参数,定义一个C#属性
- 通过
参数
属性装饰每个参数属性
- 如果要接受管道中的参数,在使用属性装饰时,请从示例
[参数(ValueFromPipeline=true)
- 要向管道提供输出,请重写管道处理方法,如和,并使用写入输出
构建项目
打开PowerShell ISE并运行以下代码:
Import-Module "PATH TO YOUR BIN DEBUG FOLDER\MyCmdlets.dll"
$suite = [MyCmdLets.Suite]::New("suite1")
$suite | Add-Set "type1" "desc1"`
| Add-Option "color1" "place1"`
| Add-Option "color2" "place2" | Out-Null
它将创建如下结构:
Name Sets
---- ----
suite1 {MyCmdlets.Set}
Type Description Options
---- ----------- -------
type1 desc1 {MyCmdlets.Option, MyCmdlets.Option}
Color Place
----- -----
color1 place1
color2 place2
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;
}
}
}
示例代码
模型类
如上所述,独立于PowerShell设计模型类,如下所示:
Name Sets
---- ----
suite1 {MyCmdlets.Set}
Type Description Options
---- ----------- -------
type1 desc1 {MyCmdlets.Option, MyCmdlets.Option}
Color Place
----- -----
color1 place1
color2 place2
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;
}
}
}
为什么使用管道?不会(对不起,我不能在注释中添加换行符,请继续想象它们)$houseSet=$suite.AddSet('doors','this represents doors')。AddOption('blue','kitchen')。AddOption('black','bedroom')。AddOption('white','doctor'))
够了吗?这是一个非复杂的折衷方案,可以在代码上工作,甚至不需要对代码进行任何更改。@ensinoctis是的,但只是管道看起来非常清晰。它说您需要用System.Management.Automation.ParameterAttribute来修饰参数,如[参数(ValueFromPipeline=true)]
注意:我将AddOption改为为为正确的模式添加选项,但如果需要,可以使用AddOption。
using System.Management.Automation;
namespace MyCmdlets
{
[Cmdlet(VerbsCommon.Add, "Set"), OutputType(typeof(Set))]
public class AddSetCmdlet : Cmdlet
{
[Parameter(ValueFromPipeline = true, Mandatory = true)]
public Suite Suite { get; set; }
[Parameter(Position = 0, Mandatory = true)]
public string Type { get; set; }
[Parameter(Position = 1, Mandatory = true)]
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 : Cmdlet
{
[Parameter(ValueFromPipeline = true, Mandatory = true)]
public Set Set { get; set; }
[Parameter(Position = 0, Mandatory = true)]
public string Color { get; set; }
[Parameter(Position = 1, Mandatory = true)]
public string Place { get; set; }
protected override void ProcessRecord() {
var option = new Option(Color, Place);
Set.Options.Add(option);
WriteObject(Set);
}
}
}