This commit is contained in:
2022-08-23 18:15:18 +10:00
parent 75928f6030
commit cc9228c209
12 changed files with 106 additions and 149 deletions

View File

@@ -1,13 +0,0 @@
namespace PowerShellBlazor.Data;
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}

View File

@@ -1,20 +0,0 @@
namespace PowerShellBlazor.Data;
public class WeatherForecastService
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
{
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray());
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace PowerShellBlazor.Models
{
public enum PSStream { Output, Information, Progress, Warning, Error }
public class Message
{
public PSStream PSStream;
public string Data;
}
}

View File

@@ -1,7 +1,6 @@
@page "/" @page "/"
@inject IPowerShellService PowerShellService @inject IPowerShellService PowerShellService
@inject IWebHostEnvironment WebHostEnvironment
@using System.Management.Automation;
<EditForm EditContext="@editContext" OnSubmit="RunScript"> <EditForm EditContext="@editContext" OnSubmit="RunScript">
<DataAnnotationsValidator /> <DataAnnotationsValidator />
<div class="mb-3"> <div class="mb-3">
@@ -16,9 +15,11 @@
</EditForm> </EditForm>
<hr /> <hr />
@foreach (MarkupString line in PowerShellService.Output) @foreach (var message in PowerShellService.Output)
{ {
@line; <div class="@message.PSStream">
@((MarkupString)message.Data)
</div>
} }
@code @code
@@ -33,14 +34,11 @@
protected void RunScript() protected void RunScript()
{ {
PowerShellService.Output = new(); PowerShellService.Output = new();
string pscommand = Path.Combine(WebHostEnvironment.ContentRootPath, "Scripts/" + script);
PowerShell shell = PowerShell.Create();
shell.AddCommand(pscommand);
PowerShellService.OutputChanged += OutputChanged; PowerShellService.OutputChanged += OutputChanged;
Task.Run(() => PowerShellService.RunScript(shell, true)); Task.Run(() => PowerShellService.RunScript(script));
} }
private void OutputChanged(object sender, List<string> newOutput) private void OutputChanged(object sender, List<Message> newOutput)
{ {
InvokeAsync(() => this.StateHasChanged()); InvokeAsync(() => this.StateHasChanged());
} }

View File

@@ -0,0 +1,27 @@
.Output {
color: black
}
.Progress {
color: green
}
.Information {
color: blue
}
.Warning::before {
content: "*** Warning ***: "
}
.Warning {
color: orange
}
.Error::before {
content: "*** Error ***: "
}
.Error {
color: red
}

View File

@@ -9,9 +9,11 @@
<ItemGroup> <ItemGroup>
<None Remove="Microsoft.PowerShell.SDK" /> <None Remove="Microsoft.PowerShell.SDK" />
<None Remove="Scripts\" /> <None Remove="Scripts\" />
<None Remove="Models\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Scripts\" /> <Folder Include="Scripts\" />
<Folder Include="Models\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.6" /> <PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.6" />

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components; global using PowerShellBlazor.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using PowerShellBlazor.Data;
using PowerShellBlazor.Services; using PowerShellBlazor.Services;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);

View File

@@ -1,5 +1,6 @@
for ($i=1; $i -le 5; $i++) { for ($i=1; $i -le 5; $i++) {
Write-Progress "Loop $i - progress output (Write-Progress)" Write-Progress "Loop $i - progress output (Write-Progress)"
Write-Information "Here's some information (Write-Information)"
Write-Output "Normal output text (Write-Output)" Write-Output "Normal output text (Write-Output)"
Write-Warning "Here's some warning text (Write-Warning)" Write-Warning "Here's some warning text (Write-Warning)"
Write-Error "Oh no, here's some error text (Write-Error)" Write-Error "Oh no, here's some error text (Write-Error)"

View File

@@ -5,9 +5,9 @@ namespace PowerShellBlazor.Services
{ {
public interface IPowerShellService public interface IPowerShellService
{ {
public List<string> Output { get; set; } public List<Message> Output { get; set; }
public Task RunScript(PowerShell shell, bool varwidth); public Task RunScript(string script);
event EventHandler<List<string>> OutputChanged; event EventHandler<List<Message>> OutputChanged;
} }
} }

View File

@@ -1,126 +1,88 @@
using System; using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Management.Automation;
namespace PowerShellBlazor.Services namespace PowerShellBlazor.Services
{ {
public class PowerShellService : IPowerShellService public class PowerShellService : IPowerShellService
{ {
public List<string> Output { get; set; } = new(); private IWebHostEnvironment _WebHostEnvironment;
private void AddOutput(string str) public PowerShellService(IWebHostEnvironment webHostEnvironment)
{ {
Output.Add(str); _WebHostEnvironment = webHostEnvironment;
}
public List<Message> Output { get; set; } = new();
private Message prevMsg = new();
private void AddOutput(PSStream stream, string message)
{
Message msg = new()
{
PSStream = stream,
Data = message
};
if (msg == prevMsg)
{
Output.Last().Data += ".";
}
else
{
Output.Add(msg);
prevMsg = msg;
}
OutputChanged.Invoke(this, Output); OutputChanged.Invoke(this, Output);
} }
public event EventHandler<List<string>> OutputChanged; public event EventHandler<List<Message>> OutputChanged;
public async Task RunScript(PowerShell shell, bool varwidth) public async Task RunScript(string script)
{ {
if (shell == null) string pscommand = Path.Combine(_WebHostEnvironment.ContentRootPath, "Scripts/" + script);
if (!File.Exists(pscommand))
{ {
AddOutput("Shell empty - nothing to execute"); AddOutput(PSStream.Error, "File not found: " + pscommand);
} }
else else
{ {
string fontstr = ""; PowerShell shell = PowerShell.Create();
if (varwidth != true) shell.AddCommand(pscommand);
{
fontstr = "face='monospace' size=3";
}
AddOutput("<b>Executing: </b>" + shell.Commands.Commands[0].ToString()); string fontstr = "";
AddOutput(PSStream.Output, "<b>Executing: </b>" + shell.Commands.Commands[0].ToString());
string prevmsg = ""; string prevmsg = "";
string msg = ""; string msg = "";
AddOutput("<br><b>BEGIN</b>"); AddOutput(PSStream.Output, "<b>BEGIN</b>");
AddOutput("<br>_________________________________________________________________________"); AddOutput(PSStream.Output, "_________________________________________________________________________");
var psOutput = new PSDataCollection<PSObject>(); var psOutput = new PSDataCollection<PSObject>();
// Collect powershell OUTPUT
psOutput.DataAdded += delegate (object? sender, DataAddedEventArgs e) psOutput.DataAdded += delegate (object? sender, DataAddedEventArgs e)
{ {
msg = psOutput[e.Index].ToString(); AddOutput(PSStream.Output, psOutput[e.Index].ToString());
};
if (msg != prevmsg)
{ shell.Streams.Information.DataAdded += delegate (object? sender, DataAddedEventArgs e)
AddOutput("<br><span><font color=black " + fontstr + ">" + msg + "</font></span>"); {
} AddOutput(PSStream.Information, shell.Streams.Information[e.Index].ToString());
else
{
AddOutput(".");
}
prevmsg = msg;
if (sender is not null)
{
var psoutput = (PSDataCollection<PSObject>)sender;
Collection<PSObject> results = psoutput.ReadAll();
}
}; };
prevmsg = "";
// Collect powershell PROGRESS output
shell.Streams.Progress.DataAdded += delegate (object? sender, DataAddedEventArgs e) shell.Streams.Progress.DataAdded += delegate (object? sender, DataAddedEventArgs e)
{ {
msg = shell.Streams.Progress[e.Index].Activity.ToString(); AddOutput(PSStream.Progress, shell.Streams.Progress[e.Index].Activity.ToString());
if (msg != prevmsg)
{
AddOutput("<br><span><font color=green " + fontstr + ">" + msg + "</font></span>");
}
else
{
AddOutput(".");
}
prevmsg = msg;
if (sender is not null)
{
var psprogress = (PSDataCollection<ProgressRecord>)sender;
Collection<ProgressRecord> results = psprogress.ReadAll();
}
}; };
prevmsg = "";
// Collect powershell WARNING output
shell.Streams.Warning.DataAdded += delegate (object? sender, DataAddedEventArgs e) shell.Streams.Warning.DataAdded += delegate (object? sender, DataAddedEventArgs e)
{ {
msg = shell.Streams.Warning[e.Index].ToString(); AddOutput(PSStream.Warning, shell.Streams.Warning[e.Index].ToString());
if (msg != prevmsg)
{
AddOutput("<br><span><font color=orange " + fontstr + "><b>***WARNING***:</b> " + msg + "</font></span>");
}
else
{
AddOutput(".");
}
prevmsg = msg;
if (sender is not null)
{
var pswarning = (PSDataCollection<WarningRecord>)sender;
Collection<WarningRecord> results = pswarning.ReadAll();
}
}; };
prevmsg = "";
// Collect powershell ERROR output
shell.Streams.Error.DataAdded += delegate (object? sender, DataAddedEventArgs e) shell.Streams.Error.DataAdded += delegate (object? sender, DataAddedEventArgs e)
{ {
msg = shell.Streams.Error[e.Index].ToString(); AddOutput(PSStream.Error, shell.Streams.Error[e.Index].ToString());
if (msg != prevmsg)
{
AddOutput("<br><span><font color=red " + fontstr + "><b>***ERROR***:</b> " + msg + "</font></span>");
}
else
{
AddOutput(".");
}
prevmsg = msg;
if (sender is not null)
{
var pserror = (PSDataCollection<ErrorRecord>)sender;
Collection<ErrorRecord> results = pserror.ReadAll();
}
}; };
// Execute powershell command // Execute powershell command
@@ -129,9 +91,8 @@ namespace PowerShellBlazor.Services
// Wait for powershell command to finish // Wait for powershell command to finish
IasyncResult.AsyncWaitHandle.WaitOne(); IasyncResult.AsyncWaitHandle.WaitOne();
AddOutput(PSStream.Output, "_________________________________________________________________________");
AddOutput("<br>_________________________________________________________________________"); AddOutput(PSStream.Output, "<b>EXECUTION COMPLETE</b>");
AddOutput("<br><b>EXECUTION COMPLETE</b>");
} }
} }
} }

View File

@@ -7,16 +7,6 @@
</div> </div>
</div> </div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
</nav>
</div>
@code { @code {
private bool collapseNavMenu = true; private bool collapseNavMenu = true;