【问题标题】:Executing Powershell Cmdlets Code in C#在 C# 中执行 Powershell Cmdlets 代码
【发布时间】:2017-04-25 18:52:23
【问题描述】:

我将如何使用用于在另一个 c# 方法而不是 powershell 脚本中创建 powershell cmdlet 的代码。

我有以下代码:

public class Program
{
    static void Main(string[] args)
    {
        var getCommand = new GetCommand { Text = "Hello World"};

        //help needed here
    }
}

[Cmdlet("Test", "Get")]
public class GetCommand : Cmdlet
{
    [Parameter(Mandatory = true)]
    public string Text { get; set; }

    protected override void ProcessRecord()
    {
        WriteObject(Text);
    }
}

【问题讨论】:

标签: c# powershell


【解决方案1】:

不要实例化 GetCommand 类 - PowerShell 会为您做到这一点!

首先,您需要启动 PowerShell 类的实例来执行您的命令:

PowerShell ps = PowerShell.Create();

然后使用AddCommand 方法添加CommandInfo 引用:

ps.AddCommand(new CmdletInfo("Test-Get", typeof(GetCommand)));

然后添加你的参数参数:

ps.AddParameter("Text", "Hello World");

现在您可以使用Invoke() 方法执行它(并收集输出):

var output = ps.Invoke();
foreach(var obj in ouput)
{
    Console.WriteLine("Output was: {0}", obj);
}

【讨论】:

    【解决方案2】:

    在单独的类中提取逻辑并直接调用它。使用 cmdlet 就可以成为这个新类的外壳。 这种关注点分离 (SoC) 还使单元测试变得更容易,并导致整体架构更简洁。

    提取类 Greeter.cs

    public class Greeter {
        public Greeter(string name) {
            _Name = name;
        }
        private string _Name;
        public string SayHello() {
            return $"Hello {_Name}";
        }
        public string SayGoodBye() {
            return $"So long {_Name}, and thanks for all the fish!";
        }
    }
    

    CommandLet GetGreetingCommand.cs

    [Cmdlet("Greeting", "Get")]
    public class GetGreetingCommand : Cmdlet {
        [Parameter(Mandatory = true)]
        public string Name { get; set; }
    
        protected override void ProcessRecord() {
            var greeter = new Greeter(Name);
            var greeting = greeter.SayHello();
            WriteObject(greeting);
        }
    }
    

    CommandLet GetGoodByeCommand .cs

    [Cmdlet("GoodBye", "Get")]
    public class GetGoodByeCommand : Cmdlet {
        [Parameter(Mandatory = true)]
        public string Name { get; set; }
    
        protected override void ProcessRecord() {
            var greeter = new Greeter(Name);
            var goodBye = greeter.SayGoodBye();
            WriteObject(goodBye);
        }
    }
    

    控制台 Main.cs(或 Greeter 类的任何其他客户端代码)

    public static void main(string[] args) {
        var greeter = new Greeter(args.FirstOrDefault());
        Console.WriteLine(greeter.SayHello());
        Console.WriteLine(greeter.SayGoodBye());
    }
    

    测试用例

    public static void SayingHelloUsesName() {
        var sut = new Greeter("Arthur");
    
        var expected = "Hello Arthur";
        var actual = sut.SayHello();
    
        Assert.AreEqual(expected, actual);
    }
    

    这里的两个问题是 - 实际的 BusinessLogic (Greeter.cs) - 与 PowerShell 的互操作性,提供参数化 cmdlet 的机制等 (Get*Command.cs)。如您所见,cmdlet 实际上只通过调用,同时通过 PowerShell 启用。

    @Mathias R. Jessen 的回答可能很有用,如果您需要调用第三方 cmdlet,但在大多数情况下,应该有一个合适的(非 powershell)API 来满足您的要求。

    【讨论】:

    • 你能举个例子吗?
    • 你去 ;)
    • @earloc 虽然这可以说是更好的分离代码,但您并没有真正解决“如何在 C# 中运行我的 PowerShell cmdlet”这个问题?
    • 我们的答案都提供了足够的策略来处理此类问题,因此提问者有更多的选择可供选择。这不就是这个平台的全部内容吗?我更喜欢用更广阔的视野来回答问题(这会翻译吗?;)),希望整体上更好的软件(开发人员)。
    • @earloc 我同意您对 stackoverflow 练习要点的解释,但存在相互竞争的议程。用户想要什么,徽章收集者和强迫症沉迷者想要什么,以及营利性公司想要什么只是松散的一致。每年他们都会问我的想法,然后当我敢于持有他们不喜欢的意见时,他们就会对投反对票感到讨厌。我已经停止投票了,很明显他们不想知道不同意见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 2013-09-23
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多