2011-09-26 16 views
9

PowerShellスクリプトを実行するアセンブリからカスタムコマンドレットを使用するC#コードからPowerShellスクリプトを実行しようとしています。コードは次のとおりです。Hosted PowerShellで同じアセンブリ内のコマンドレットが表示されない

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またはRunspaceなどでCmdletを登録するために必要なことはありますか?

答えて

9

あなたの現在のコードスニペットでこれを行う最も簡単な方法は、このようなものです:

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です。

+0

魅力的な作品です!ありがとう! –

1

Powershellセッションで使用するには、コマンドレットを登録する必要があります。一般的にはPowershell Snap-Inを使用して行います。ここでは、プロセスの高レベルの概要です:

  • (すでにこの部分をやった)カスタムコマンドレットを作成Powershellのスナップインを作成し、あなたのコマンドレットが含まれていると説明した
  • 新しいスナップをインストールします。使用して、特定のPowerShellセッションにスナップインを追加Installutil
  • を使用して、システム上-in Add-PSSnapin

番目を説明するMSDN上のカップルの便利な記事があります。かなり徹底的にE工程:

カスタムコマンドレットを書いについて説明しByteBlocks上の2部構成のシリーズもあります。あなたはパート1と同等のことをしているようですので、そのシリーズがベストベットになるかもしれません。あなたはクイックリファレンスとしてパート2を使用して、うまくいくことができます。

+1

スナップインはPowerShell v1のやり方であり、管理者権限を必要とするため、最近は使用しないでください。 Powershell v2モジュールを使用しているはずです。 – x0n

+0

彼は何をしようとしているのかという質問に本当に答えません。 – manojlds

+0

@manojldsそれは質問に答えますが、x0nの答えほど間違いなく最新ではありません。 – ajk

4

さらに簡単な方法は、コマンドレットをランスペース構成に登録し、この構成でランスペースを作成し、そのランスペースを使用することです。

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); 
    } 
} 

この方法では、コマンドレットクラスを公開する必要はありません。

+0

ありがとうございます。PowerShellの内部からこれを行う方法はありますか?つまり、[Reflection.Assembly] :: LoadFromを使用してDLLをロードして、PowerShellの現在のセッションにコマンドレットを読み込む関数を呼び出しますか? –

+0

私はそれを試していませんでした。 PowerShellでは、既定の(多少の*現在の*ただしそれに依存する)実行空間の構成にアクセスできます。 '[System.Management.Automation.Runspaces.Runspace] :: DefaultRunspace.RunspaceConfiguration'。次に、.Cmdlets.Append(...)を呼び出してみます。これを試して結果を教えていただければ幸いです。 –

+0

私はそれを働かせることができません。 Runspaceは、BeforeOpen状態でない限り、そうした方法でCmdletをロードしないようです。 Cmdletを別の場所にロードする方法は何ですか? –

関連する問題