2009-07-18 17 views
8

AMAÇ

  • Ben bir PowerShell modülünde bir cmdlet yazıyorum
  • Windows 7 üzerinde PowerShell 2.0 kullanıyorum ("modül den çağrıldığında bir PowerShell cmdlet en ayrıntılı çıktı nasıl yakalanır "Powershell 2.0’da yenidir."
  • cmdlet'i test etmek için Visual Studio 2008'de cmdlet'i programsal olarak çağıran Birim testleri yazarım.

REFERANS denilen

  • This Article on MSDN "Bir cmdlet içinde bir Cmdlet Çağır nasıl" C# bir cmdlet'ini çağırmak için nasıl gösterir.

    cmdlet programlı C#

    : Eğer açıkça yaşıyorum sorunu görebileceği şekilde

Bu benim gerçek kod distile versiyonudur

  • KAYNAK KOD — Ben mümkün olduğunca küçük hale getirdik

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

YORUMLAR

  • Powershell komut satırından ayrıntılı çıkışın nasıl etkinleştirileceğini ve kaydedileceğini anlıyorum; Bu sorun değil.
  • Bu durumda Cd'den cmdlet'i program aracılığıyla çağırıyorum.
  • Belirli bir senaryoyu adresler buldunuz. Bazı makaleler kendi PSHost'umu uygulamamı önerir ama pahalı görünüyor ve ayrıca cmdlet'i metin olarak çağırmak gibi gözüküyor, ki bu da çok fazla yazılmadığından kaçınmak istiyorum. İşte 2009-07-20

    olduğu AÇIK

GÜNCELLEME aşağıda Yanıta göre kaynak kodudur.

Bazı şeyler hala bana net değildir: * (ideal ps Objet bir dize olarak geçmek zorunda kalmadan) "Get-Renkler" cmdlet'i çağrı * Nasıl Nasıl ayrıntılı çıktı olarak almak için Sonunda bir koleksiyon almak yerine oluşturulur.

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

      } 

     } 
    } 

Yukarıdaki kod bu çıktıyı oluşturur: Powershell sınıfını kullanarak

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

GÜNCELLEME

2010-01-16 AÇIK (System.Management.Automation ama sadece sürümünde bulunan PowerShell 2.0 SDK ile birlikte gelen montajın, Windows 7'de hangi kutudan çıktığı değil. Programlı olarak cmdlet'i arayabilir ve ayrıntılı çıktı alabilirim. Geriye kalan kısım aslında bu powershell örneğine özel bir cmdlet eklemektir - çünkü bu benim asıl amacımdı - birimime cmdlet'leri powershell ile gelenleri test etmem.$VerbosePreference en azından ayarlanmadığı sürece

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"); 
    } 
} 
+1

Yanıtımda eksik bir backtick vardı - bu, $ verbosepreference değişkeninin önceden değerlendirilmesini önler. – x0n

+0

Cevabımı neden cevap olarak işaretlemediniz? – x0n

+0

Gerçek zamanlı ayrıntılı kayıtlar isterseniz, powershell örneğinin akış özellikindeki datachanged olaya abone olun. – x0n

cevap

10
  • Ayrıntılı çıkış aslında çıkış değil "devam edin."
  • kullanın PowerShell türü cmdlet çalıştırın ve powershell komut Streams.Verbose propery

Örnek dan VerboseRecord örneklerini okumak için:

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} 

Bu C# çevirmek kolay olmalıdır.

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.  } 

Önemli çizgiler hat 5 ve oturum için ve yaklaşan yeni komutlar ve komut dosyaları için 6. Bu temelde set $ verbosepreference vardır.