9

バックグラウンド

  • Windows 7 で Powershell 2.0 を使用しています。
  • Powershell モジュールでコマンドレットを作成しています (「モジュール」は Powershell 2.0 の新機能です)。
  • コマンドレットをテストするために、Visual Studio 2008 でコマンドレットをプログラムで呼び出す単体テストを作成しています。

参照

ソースコード

  • これは私の実際のコードの要約版です — 私が抱えている問題をはっきりと見ることができるように、コードをできるだけ小さくしました:

    using System;
    using System.Management.Automation;   
    
    namespace DemoCmdLet1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var cmd = new GetColorsCommand();
    
                    foreach ( var i in cmd.Invoke<string>())
                    {
                       Console.WriteLine("- " + i );   
                    } 
               } 
           } 
    
        [Cmdlet("Get", "Colors")]
        public class GetColorsCommand : Cmdlet
        {
            protected override void ProcessRecord()
            {
                this.WriteObject("Hello");
                this.WriteVerbose("World");
            }
    
        }
    }
    

コメント

  • Powershell コマンド ラインから詳細出力を有効にしてキャプチャする方法を理解しています。それは問題ではありません。
  • この場合、C# からコマンドレットをプログラムで呼び出しています。
  • 私が見つけたものは、私の特定のシナリオに対応していません。一部の記事では、独自の PSHost を実装する必要があると示唆されていますが、費用がかかるようであり、コマンドレットをテキストとして呼び出す必要があるようにも思えます。

2009 年 7 月 20 日の更新

これは、以下の回答に基づくソースコードです。

* 「Get-Colors」コマンドレットを呼び出す方法 (理想的には、文字列として ps オブジェクトに渡す必要はありません)最後にそれらのコレクション。

    using System;
    using System.Management.Automation;   

    namespace DemoCmdLet1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var ps = System.Management.Automation.PowerShell.Create();

                ps.Commands.AddScript("$verbosepreference='continue'; write-verbose 42");

                foreach ( var i in ps.Invoke<string>())
                {
                   Console.WriteLine("normal output: {0}" , i );   
                }
                foreach (var i in ps.Streams.Verbose)
                {
                    Console.WriteLine("verbose output: {0}" , i);
                }

            }
        }

        [Cmdlet("Get", "Colors")]
        public class GetColorsCommand : Cmdlet
        {
            protected override void ProcessRecord()
            {
                this.WriteObject("Red");
                this.WriteVerbose("r");
                this.WriteObject("Green");
                this.WriteVerbose("g");
                this.WriteObject("Blue");
                this.WriteVerbose("b");

            }

        }
    }

上記のコードは、次の出力を生成します。

d:\DemoCmdLet1\DemoCmdLet1>bin\Debug\DemoCmdLet1.exe
verbose output: 42

2010 年 1 月 16 日の更新

Powershell クラス (System.Management.Automation にありますが、Powershell 2.0 SDK に付属するアセンブリのバージョンにのみあり、Windows 7 ですぐに使用できるものではありません) を使用して、コマンドレットをプログラムで呼び出すことができます。詳細な出力を取得します。残りの部分は、実際にカスタム コマンドレットをその PowerShell インスタンスに追加することです。それが私の当初の目標だったので、PowerShell に付属するコマンドレットではなく、コマンドレットを単体テストすることです。

class Program
{
    static void Main(string[] args)
    {
        var ps = System.Management.Automation.PowerShell.Create();
        ps.AddCommand("Get-Process");
        ps.AddParameter("Verbose");
        ps.Streams.Verbose.DataAdded += Verbose_DataAdded;
        foreach (PSObject result in ps.Invoke())
        {
            Console.WriteLine(
                    "output: {0,-24}{1}",
                    result.Members["ProcessName"].Value,
                    result.Members["Id"].Value);
        } 
        Console.ReadKey();
    }

    static void Verbose_DataAdded(object sender, DataAddedEventArgs e)
    {
        Console.WriteLine( "verbose output: {0}", e.Index);
    }
}


[Cmdlet("Get", "Colors")]
public class GetColorsCommand : Cmdlet
{
    protected override void ProcessRecord()
    {
        this.WriteObject("Hello");
        this.WriteVerbose("World");
    }
}
4

3 に答える 3

10
  • $VerbosePreference少なくとも「続行」に設定されていない限り、詳細出力は実際には出力されません。
  • PowerShellタイプを使用してを実行し、プロパティからインスタンスcmdletを読み取りますVerboseRecordStreams.Verbose

PowerShellスクリプトの例:

ps> $ps = [powershell]::create()
ps> $ps.Commands.AddScript("`$verbosepreference='continue'; write-verbose 42")
ps> $ps.invoke()
ps> $ps.streams.verbose
Message   InvocationInfo                          PipelineIterationInfo
-------   --------------                          ---------------------
42        System.Management.Automation.Invocat... {0, 0}

これは、C#に簡単に変換できるはずです。

于 2009-07-18T03:44:00.957 に答える
0
1.        string scriptFile = "Test.ps1";
2.        using (PowerShell ps = PowerShell.Create())
3.        {
4.          const string getverbose = "$verbosepreference='continue'"; 
5.          ps.AddScript(string.Format(getverbose));
6.          ps.Invoke();
7.          ps.Commands.Clear();
8.          ps.AddScript(@".\" + scriptFile);
9.          ps.Invoke();
10.         foreach (var v in ps.Streams.Verbose)
11.         {
12.               Console.WriteLine(v.Message);
13.         }
14.       }

重要な行は 5 行目と 6 行目です。これは基本的に、セッションと今後の新しいコマンドとスクリプトの $verbosepreference を設定します。

于 2014-03-25T20:14:06.483 に答える