Pergunta

Estou executando um script de teste Powershell partir de uma aplicação C #. O script pode falhar devido a uma má cmdlet que faz com que pipe.Invoke () para lançar uma exceção.

Eu sou capaz de capturar todas as informações que precisa sobre a exceção, mas eu gostaria de ser capaz de exibir a saída do script até esse ponto. Eu não tive nenhuma sorte já que os resultados parece ser nulo quando uma exceção é lançada.

Existe algo que eu estou perdendo? Obrigado!

m_Runspace = RunspaceFactory.CreateRunspace();
m_Runspace.Open();
Pipeline pipe = m_Runspace.CreatePipeline();
pipe.Commands.AddScript(File.ReadAllText(ScriptFile));
pipe.Commands.Add("Out-String");
try {
   results = pipe.Invoke();
}
catch (System.Exception)
{
   m_Runspace.Close();
   // How can I get to the Powershell output that comes before the exception?
}
Foi útil?

Solução 2

A solução acabei usando foi implementar nosso próprio PSHost para lidar com a saída do PowerShell. A informação inicial para este veio de http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx na seção "Construindo um anfitrião PS personalizado".

No meu caso, foi necessário utilizar um PSHostRawUserInterface costume também.

Aqui está uma rápida visão geral do que foi feito. Eu só listou a função que eu realmente implimented, mas há muitos que estão apenas conter lançar nova NotImplementedException ();

private class myPSHost : PSHost
{
   (Same as what the above link mentions)
}
private class myPSHostUI : PSHostUserInterface
{
   private myPSHostRawUI rawui = new myPSHostRawUI();

   public override void Write // all variations
   public override PSHostRawUserInterface RawUI { get { return rawui; } }

}
private class myPSHostRawUI : PSHostRawUserInterface
{
   public override ConsoleColor ForegroundColor
   public override ConsoleColor BackgroundColor
   public override Size BufferSize
}

Outras dicas

Não sei se isso é útil. Eu estou supondo que você está executando V1. Esta abordagem V2 não joga e imprime o resultado:

Hello World
67 errors

string script = @"
  'Hello World'
  ps | % {
    $_.name | out-string1
  }
";

PowerShell powerShell = PowerShell.Create();

powerShell.AddScript(script);
var results = powerShell.Invoke();

foreach (var item in results)
{
  Console.WriteLine(item);
}

if (powerShell.Streams.Error.Count > 0)
{
  Console.WriteLine("{0} errors", powerShell.Streams.Error.Count);
}

Eu tenho o mesmo problema. A maneira mais fácil de obter uma saída quando pipe.Invoke () lança uma exceção é para uso Chamar (entrada IEnumerable, saída IList)

exemplo mostra como obter todas as saídas, erro, diminuindo etc. na ordem correta

script do PowerShell

Write-Output "Hello world" 
Write-Error "Some error"
Write-Warning "Some warning"
throw "Some exception"

C #

List<string> RunLog = new List<string>(); 

using (System.Management.Automation.PowerShell psInstance = System.Management.Automation.PowerShell.Create())

{
    psInstance.AddScript(_Script);

psInstance.Streams.Error.DataAdded += (sender, args) =>
{
    ErrorRecord err = ((PSDataCollection<ErrorRecord>)sender)[args.Index];
    RunLog.Add($"ERROR: {err}");
};

psInstance.Streams.Warning.DataAdded += (sender, args) =>
{
    WarningRecord warning = ((PSDataCollection<WarningRecord>)sender)[args.Index];
    RunLog.Add($"WARNING: {warning}");
};

... etc ...

var result = new PSDataCollection<PSObject>();
result.DataAdded += (sender, args) =>
{
    PSObject output = ((PSDataCollection<PSObject>)sender)[args.Index];
    RunLog.Add($"OUTPUT: {output}");
};

try
{
    psInstance.Invoke(null, result);
}
catch(Exception ex)
{
    RunLog.Add($"EXCEPTION: {ex.Message}");
}                                                
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top