CONTESTO
- Sto usando PowerShell 2.0 su Windows 7.
- Sto scrivendo un cmdlet in un modulo PowerShell ("modulo "è nuovo di Powershell 2.0).
- Per testare il cmdlet, sto scrivendo i test delle unità in Visual Studio 2008 che richiamano a livello di codice il cmdlet.
RIFERIMENTO
- This Article on MSDN chiamato "come richiamare un cmdlet dall'interno di un Cmdlet" mostra come chiamare un cmdlet da C#.
IL CODICE SORGENTE
Questa è una versione distillata del mio codice attuale — Ho fatto il più piccolo possibile in modo che si può vedere il problema che sto avendo chiaramente:Come catturare output dettagliato di un cmdlet PowerShell quando il cmdlet è a livello di codice richiamato da C#
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"); } } }
COMMENTI
- Capisco come abilitare e catturare l'output dettagliato dalla riga di comando di Powershell; non è questo il problema
- In questo caso sto richiamando a livello di codice il cmdlet da C#.
- Nulla di ciò che ho trovato riguarda il mio specifico scenario. Alcuni articoli suggeriscono che dovrei implementare il mio PSHost, ma sembra costoso e sembra anche dover chiamare il cmdlet come testo, che vorrei evitare perché non è così fortemente digitato.
AGGIORNAMENTO SULLA 2009-07-20
Ecco è il codice sorgente in base alla risposta qui sotto.
Alcune cose non sono ancora chiaro per me: * Come chiamare i "Get-Colors" cmdlet (idealmente senza dover passare come una stringa al ps objet) * Come ottenere l'output dettagliato come viene generato invece di ricevere una raccolta alla fine.
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");
}
}
}
Il codice precedente genera questo output:
d:\DemoCmdLet1\DemoCmdLet1>bin\Debug\DemoCmdLet1.exe
verbose output: 42
AGGIORNAMENTO SULLA 2010-01-16
utilizzando la classe PowerShell (trovato in System.Management.Automation, ma solo nella versione dell'assembly fornito con l'SDK di PowerShell 2.0, non quello che viene fornito in Windows 7) Posso chiamare a livello di programmazione il cmdlet e ottenere l'output dettagliato. La parte rimanente è di aggiungere effettivamente un cmdlet personalizzato all'istanza di PowerShell, poiché questo era il mio obiettivo originale: testare i miei cmdlet non quelli forniti con 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");
}
}
c'era un "backtick mancante" nella mia risposta - questo impedisce alla variabile $ verbosepreference di essere valutata prima del tempo. – x0n
Perché non hai contrassegnato la mia risposta come risposta? – x0n
Se si desiderano record dettagliati in tempo reale, sottoscrivere l'evento datachanged nella proprietà di streaming dell'istanza di PowerShell. – x0n