Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#13 - Immediate Powershell Output #23

Merged
merged 1 commit into from
Mar 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions src/PowerShell.Tests/Tests/FileTests.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
#region Using Statements
using System;
using System.IO;
using System.Collections.ObjectModel;

using Xunit;

using System.Management.Automation;
using System.Management.Automation.Runspaces;

using Cake.Core.Diagnostics;
using Cake.Core.IO;
using Cake.Powershell;
using Cake.Core.IO;
using System.Collections.ObjectModel;
using System.Management.Automation;
using Xunit;
#endregion


Expand All @@ -36,7 +28,7 @@ public void Should_Start_File_With_Parameters()
Collection<PSObject> results = CakeHelper.CreatePowershellRunner().Start(new FilePath("../../Scripts/Test.ps1"),
new PowershellSettings().WithArguments(args => args.Append("Service", "eventlog")));

Assert.True((results != null) && (results.Count == 1), "Check Rights");
Assert.True((results != null) && (results.Count >= 1), "Check Rights");
}


Expand Down
120 changes: 74 additions & 46 deletions src/Powershell/Runner/PowershellRunner.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
#region Using Statements
using System;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Security.Principal;

using Cake.Core;
using Cake.Core.IO;
using Cake.Core.IO.Arguments;
using Cake.Core.Diagnostics;

using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Cake.Core;
using Cake.Core.Diagnostics;
using Cake.Core.IO;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Net;
using System.Threading;

#endregion


Expand All @@ -27,9 +22,13 @@ namespace Cake.Powershell
/// </summary>
public sealed class PowershellRunner : IPowershellRunner
{
#region Fields (2)
#region Fields (5)
private readonly ICakeEnvironment _Environment;
private readonly ICakeLog _Log;
private Collection<PSObject> _pipelineResults = new Collection<PSObject>();
private bool _complete;
private bool _successful = true;

#endregion


Expand Down Expand Up @@ -270,7 +269,6 @@ private Collection<PSObject> Invoke(string script, PowershellSettings settings)


//Create Pipline
Collection<PSObject> results = null;

using (Pipeline pipeline = runspace.CreatePipeline())
{
Expand All @@ -290,30 +288,17 @@ private Collection<PSObject> Invoke(string script, PowershellSettings settings)

if (settings.FormatOutput)
{
pipeline.Commands.Add("Out-String");
pipeline.Commands.Add("Out-Default");
}

results = pipeline.Invoke();


pipeline.Output.DataReady += Output_DataReady;
pipeline.Error.DataReady += Error_DataReady;
pipeline.StateChanged += Pipeline_StateChanged;
pipeline.InvokeAsync();

//Log Errors
if (pipeline.Error.Count > 0)
while (!_complete)
{
while (!pipeline.Error.EndOfPipeline)
{
PSObject value = (PSObject)pipeline.Error.Read();

if (value != null)
{
ErrorRecord record = (ErrorRecord)value.BaseObject;

if (record != null)
{
_Log.Error(Verbosity.Normal, record.Exception.Message);
}
}
}
Thread.Sleep(500);
}
}

Expand All @@ -322,17 +307,60 @@ private Collection<PSObject> Invoke(string script, PowershellSettings settings)



//Log Results
if (settings.LogOutput)
return _pipelineResults;
}

private void Pipeline_StateChanged(object sender, PipelineStateEventArgs e)
{
if (e.PipelineStateInfo.State != PipelineState.Completed && e.PipelineStateInfo.State != PipelineState.Failed && e.PipelineStateInfo.State != PipelineState.Stopped) return;

if (e.PipelineStateInfo.State == PipelineState.Failed)
{
foreach (PSObject res in results)
{
_Log.Debug(Verbosity.Normal, this.FormatLogMessage(res.ToString()));
}
var failedPso = new PSObject(e.PipelineStateInfo.Reason);
_pipelineResults.Add(failedPso);
_successful = false;
}

return results;
var pso = new PSObject(_successful ? 0 : 1);
_pipelineResults.Insert(0, pso);

_complete = true;
}

private void Error_DataReady(object sender, EventArgs e)
{
var error = sender as PipelineReader<object>;

if (error == null) return;

if (_successful && error.Count > 0)
{
_successful = false;
}

while (error.Count > 0)
{
var errorItem = error.Read();
var pso = new PSObject(errorItem);
_pipelineResults.Add(pso);
_Log.Error(Verbosity.Normal, this.FormatLogMessage(errorItem.ToString()));
}
}

private void Output_DataReady(object sender, EventArgs e)
{
var output = sender as PipelineReader<PSObject>;

if (output == null) return;

while (output.Count > 0)
{
var outputItem = output.Read();
_pipelineResults.Add(outputItem);
_Log.Debug(Verbosity.Normal, this.FormatLogMessage(outputItem.ToString()));
}
}

#endregion
}
}