托管 PowerShell 无法在同一程序集中看到 Cmdlet

发布于 2024-12-06 21:27:56 字数 750 浏览 2 评论 0原文

我正在尝试从我的 C# 代码运行 PowerShell 脚本,这将使用运行它们的程序集中的自定义 Cmdlet。这是代码:

using System;
using System.Management.Automation;

[Cmdlet(VerbsCommon.Get,"Hello")]
public class GetHelloCommand:Cmdlet
{
    protected override void EndProcessing()
    {
        WriteObject("Hello",true);
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        PowerShell powerShell=PowerShell.Create();
        powerShell.AddCommand("Get-Hello");
        foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>())
            Console.WriteLine(str);
    }
}

当我尝试运行它时,我收到 CommandNotFoundException。 我的 Cmdlet 写错了吗?我需要做些什么才能在 PowerShell 或运行空间等中注册我的 Cmdlet 吗?

I'm trying to run PowerShell scripts from my C# code, that will use custom Cmdlets from the assembly that runs them. Here is the code:

using System;
using System.Management.Automation;

[Cmdlet(VerbsCommon.Get,"Hello")]
public class GetHelloCommand:Cmdlet
{
    protected override void EndProcessing()
    {
        WriteObject("Hello",true);
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        PowerShell powerShell=PowerShell.Create();
        powerShell.AddCommand("Get-Hello");
        foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>())
            Console.WriteLine(str);
    }
}

When I try to run it, I get a CommandNotFoundException.
Did I write my Cmdlet wrong? Is there something I need to do to register my Cmdlet in PowerShell or in the Runspace or something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疯到世界奔溃 2024-12-13 21:27:56

使用当前代码片段执行此操作的最简单方法如下:

using System; 
using System.Management.Automation; 

[Cmdlet(VerbsCommon.Get,"Hello")] 
public class GetHelloCommand:Cmdlet 
{ 
    protected override void EndProcessing() 
    { 
        WriteObject("Hello",true); 
    } 
} 

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
        PowerShell powerShell=PowerShell.Create();

        // import commands from the current executing assembly
        powershell.AddCommand("Import-Module")
            .AddParameter("Assembly",
                  System.Reflection.Assembly.GetExecutingAssembly())
        powershell.Invoke()
        powershell.Commands.Clear()

        powershell.AddCommand("Get-Hello"); 
        foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>()) 
            Console.WriteLine(str); 
    } 
} 

这里假设 PowerShell v2.0(您可以使用 $psversiontable 或按版权日期(应为 2009 年)检查控制台。)如果您使用的是 win7,则正在使用 v2。

The easiest way to do this with your current code snippet is like this:

using System; 
using System.Management.Automation; 

[Cmdlet(VerbsCommon.Get,"Hello")] 
public class GetHelloCommand:Cmdlet 
{ 
    protected override void EndProcessing() 
    { 
        WriteObject("Hello",true); 
    } 
} 

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
        PowerShell powerShell=PowerShell.Create();

        // import commands from the current executing assembly
        powershell.AddCommand("Import-Module")
            .AddParameter("Assembly",
                  System.Reflection.Assembly.GetExecutingAssembly())
        powershell.Invoke()
        powershell.Commands.Clear()

        powershell.AddCommand("Get-Hello"); 
        foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>()) 
            Console.WriteLine(str); 
    } 
} 

This assumes PowerShell v2.0 (you can check in your console with $psversiontable or by the copyright date which should be 2009.) If you're on win7, you are on v2.

Hello爱情风 2024-12-13 21:27:56

另一种简单的方法是在运行空间配置中注册 cmdlet,使用此配置创建运行空间,然后使用该运行空间。

using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

[Cmdlet(VerbsCommon.Get, "Hello")]
public class GetHelloCommand : Cmdlet
{
    protected override void EndProcessing()
    {
        WriteObject("Hello", true);
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        PowerShell powerShell = PowerShell.Create();
        var configuration = RunspaceConfiguration.Create();
        configuration.Cmdlets.Append(new CmdletConfigurationEntry[] { new CmdletConfigurationEntry("Get-Hello", typeof(GetHelloCommand), "") });
        powerShell.Runspace = RunspaceFactory.CreateRunspace(configuration);
        powerShell.Runspace.Open();

        powerShell.AddCommand("Get-Hello");
        foreach (string str in powerShell.AddCommand("Out-String").Invoke<string>())
            Console.WriteLine(str);
    }
}

为了以防万一,使用这种方法 cmdlet 类不必是公共的。

Yet another simple way is to register cmdlets in a runspace configuration, create a runspace with this configuration, and use that runspace.

using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

[Cmdlet(VerbsCommon.Get, "Hello")]
public class GetHelloCommand : Cmdlet
{
    protected override void EndProcessing()
    {
        WriteObject("Hello", true);
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        PowerShell powerShell = PowerShell.Create();
        var configuration = RunspaceConfiguration.Create();
        configuration.Cmdlets.Append(new CmdletConfigurationEntry[] { new CmdletConfigurationEntry("Get-Hello", typeof(GetHelloCommand), "") });
        powerShell.Runspace = RunspaceFactory.CreateRunspace(configuration);
        powerShell.Runspace.Open();

        powerShell.AddCommand("Get-Hello");
        foreach (string str in powerShell.AddCommand("Out-String").Invoke<string>())
            Console.WriteLine(str);
    }
}

Just in case, with this approach cmdlet classes do not have to be public.

孤芳又自赏 2024-12-13 21:27:56

您确实需要先注册 cmdlet,然后才能在 Powershell 会话中使用它。您通常可以通过 Powershell 管理单元来完成此操作。以下是该过程的高级概述:

  • 创建自定义 cmdlet(您已经完成了这部分)
  • 创建包含并描述您的 cmdlet 的 Powershell 管理单元
  • 使用 Installutil在系统上安装新的管理单元 使用
  • Add-PSSnapin 将管理单元添加到特定的 Powershell 会话

MSDN 上有几篇有用的文章非常彻底地解释了该过程:

还有一个有关 ByteBlocks 的两部分系列,讨论编写自定义 cmdlet。该系列可能是您最好的选择,因为您似乎已经完成了与第 1 部分相同的工作。您也许可以仅使用第 2 部分作为快速参考,然后就可以开始了。

You do need to register your cmdlet before you can use it in a Powershell session. You'll generally do that by way of a Powershell Snap-In. Here's a high-level overview of the process:

  • Create custom cmdlets (you've already done this part)
  • Create a Powershell Snap-in which contains and describes your cmdlets
  • Install the new Snap-in on your system using Installutil
  • Add the Snap-in to a specific Powershell session using Add-PSSnapin

There are a couple useful articles on MSDN that explain the process pretty thoroughly:

There's also a 2-part series on ByteBlocks that discusses writing custom cmdlets. That series may be your best bet, since you seem to have done the equivalent of part 1 already. You may be able to just use part 2 as a quick reference and be good to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文