Skip to content

Commit

Permalink
Fix initialization ...
Browse files Browse the repository at this point in the history
Make sure the runner and it's queue are created at construction
Add a command to the OnInitialized event in the demo app, to prove it works now
  • Loading branch information
Jaykul committed Jul 30, 2015
1 parent 7cbd492 commit 9b52a39
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 53 deletions.
24 changes: 13 additions & 11 deletions PoshCode.PoshConsole/PoshConsole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,9 @@ protected override void OnInitialized(EventArgs e)

Loaded += (sender, ignored) =>
{
if (Runner == null)
if (!Runner.IsInitialized)
{
Runner = new RunspaceProxy(_host);
Runner.RunspaceReady += (source, args) => Dispatcher.BeginInvoke((Action) (() =>
{
CommandBox.IsEnabled = true;
ExecutePromptFunction(null, PipelineState.Completed);
}));

// TODO: Improve this interface
Expander.TabComplete = Runner.CompleteInput;
Runner.Initialize();
}
};
}
Expand Down Expand Up @@ -226,7 +218,17 @@ public PoshConsole()
str.Append(obj);
}
Prompt(str.ToString());
}) { DefaultOutput = false, Secret = true };
}) { DefaultOutput = false, Secret = true };

Runner = new RunspaceProxy(_host);
Runner.RunspaceReady += (source, args) => Dispatcher.BeginInvoke((Action)(() =>
{
CommandBox.IsEnabled = true;
ExecutePromptFunction(null, PipelineState.Completed);
}));

// TODO: Improve this interface
Expander.TabComplete = Runner.CompleteInput;
}

public Command DefaultOutputCommand { get; set; }
Expand Down
82 changes: 41 additions & 41 deletions PoshCode.PoshConsole/PowerShell/RunspaceProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,43 +31,36 @@ internal class RunspaceProxy
public event RunspaceReadyHandler RunspaceReady;


private SyncEvents _syncEvents = new SyncEvents();
private readonly Runspace _runSpace;
private readonly SyncEvents _syncEvents = new SyncEvents();
private Runspace _runSpace;

public Pipeline _pipeline;
private Pipeline _pipeline;

public Command DefaultOutputCommand { get; private set; }
public Command ContentOutputCommand { get; set; }


protected Queue<CallbackCommand> CommandQueue { get; private set; }
protected Queue<CallbackCommand> CommandQueue { get; }
protected Thread WorkerThread;


protected InitialSessionState InitialSessionState => _runSpace.InitialSessionState;

public InitialSessionState InitialSessionState
{
get { return _runSpace.InitialSessionState; }
}

public RunspaceConfiguration RunspaceConfiguration
{
get { return _runSpace.RunspaceConfiguration; }
}
protected RunspaceConfiguration RunspaceConfiguration => _runSpace.RunspaceConfiguration;

public RunspaceStateInfo RunspaceStateInfo
{
get { return _runSpace.RunspaceStateInfo; }
}
protected RunspaceStateInfo RunspaceStateInfo => _runSpace.RunspaceStateInfo;

private Host _host;
private readonly Host _host;

public RunspaceProxy(Host host)
{
_host = host;
CommandQueue = new Queue<CallbackCommand>();
}

public bool IsInitialized => _runSpace != null;

public void Initialize() {
// pre-create reusable commands
DefaultOutputCommand = new Command("Out-Default");
//// for now, merge the errors with the rest of the output
Expand Down Expand Up @@ -120,13 +113,13 @@ public RunspaceProxy(Host host)
var path = Path.GetDirectoryName(poshModule.Location);
iss.ImportPSModulesFromPath(Path.Combine(path, "Modules"));

var profile = new PSObject(Path.GetFullPath(Path.Combine(currentUserProfilePath, host.Name + "_profile.ps1")));
var profile = new PSObject(Path.GetFullPath(Path.Combine(currentUserProfilePath, _host.Name + "_profile.ps1")));
//* %windir%\system32\WindowsPowerShell\v1.0\profile.ps1
// This profile applies to all users and all shells.
profile.Properties.Add(new PSNoteProperty("AllUsersAllHosts", Path.GetFullPath(Path.Combine(systemProfilePath, "Profile.ps1"))));
//* %windir%\system32\WindowsPowerShell\v1.0\PoshConsole_profile.ps1
// This profile applies to all users, but only to the Current shell.
profile.Properties.Add(new PSNoteProperty("AllUsersCurrentHost", Path.GetFullPath(Path.Combine(systemProfilePath, host.Name + "_profile.ps1"))));
profile.Properties.Add(new PSNoteProperty("AllUsersCurrentHost", Path.GetFullPath(Path.Combine(systemProfilePath, _host.Name + "_profile.ps1"))));
//* %UserProfile%\My Documents\WindowsPowerShell\profile.ps1
// This profile applies only to the current user, but affects all shells.
profile.Properties.Add(new PSNoteProperty("CurrentUserAllHosts", Path.GetFullPath(Path.Combine(currentUserProfilePath, "Profile.ps1"))));
Expand All @@ -143,7 +136,7 @@ public RunspaceProxy(Host host)
iss.Assemblies.Add(new SessionStateAssemblyEntry(sma.FullName, sma.CodeBase));
*/

_runSpace = RunspaceFactory.CreateRunspace(host, iss);
_runSpace = RunspaceFactory.CreateRunspace(_host, iss);

// TODO: can we handle profiles this way?
/*
Expand Down Expand Up @@ -417,28 +410,35 @@ internal void ExecuteShutdownProfile(int exitCode)
/// </summary>
private void ExecuteStartupProfile()
{
CommandQueue.Clear();

Enqueue(new CallbackCommand(new[] { new Command(Resources.Prompt, true, true) }, null) { Secret = true });

Enqueue(new CallbackCommand(new[] { new Command(Resources.TabExpansion2, true, true) }, null) { Secret = true });
// we're going to ensure the startup profile goes _first_
lock (((ICollection) CommandQueue).SyncRoot)
{
CallbackCommand[] commands = new CallbackCommand[CommandQueue.Count];
CommandQueue.CopyTo(commands, 0);
CommandQueue.Clear();

var existing = (
from profileVariable in InitialSessionState.Variables["profile"]
from pathProperty in ((PSObject) profileVariable.Value).Properties.Match("*Host*", PSMemberTypes.NoteProperty)
where File.Exists(pathProperty.Value.ToString())
select pathProperty.Value.ToString()
).Select(path => new Command(path, false, true)).ToArray();
// This might be nice to have too (in case anyone was using it):
_runSpace.SessionStateProxy.SetVariable("profiles", existing.ToArray());

if (existing.Any())
{
CommandQueue.Enqueue(new CallbackCommand(existing,
ignored => RunspaceReady(this, _runSpace.RunspaceStateInfo.State)) {Secret = true});
// this is super important
}

var existing = (
from profileVariable in InitialSessionState.Variables["profile"]
from pathProperty in ((PSObject)profileVariable.Value).Properties.Match("*Host*", PSMemberTypes.NoteProperty)
where File.Exists(pathProperty.Value.ToString())
select pathProperty.Value.ToString()
).Select(path => new Command(path, false, true)).ToArray();
// This might be nice to have too (in case anyone was using it):
_runSpace.SessionStateProxy.SetVariable("profiles", existing.ToArray());
CommandQueue.Enqueue(new CallbackCommand(new[] {new Command(Resources.Prompt, true, true)}, null) {Secret = true});

if (existing.Any())
{
Enqueue(new CallbackCommand( existing, ignored => RunspaceReady(this, _runSpace.RunspaceStateInfo.State)) { Secret = true }); // this is super important
}
else
{
Enqueue(new CallbackCommand( "New-Paragraph", ignored => RunspaceReady(this, _runSpace.RunspaceStateInfo.State)) { Secret = true }); // this is super important
foreach (var command in commands)
{
CommandQueue.Enqueue(command);
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion PoshConsole.Demo/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Media;
using Fluent;

Expand All @@ -18,5 +19,12 @@ private void ZoomSlider_OnValueChanged(object sender, RoutedPropertyChangedEvent
{
TextOptions.SetTextFormattingMode(this, e.NewValue > 1.0 ? TextFormattingMode.Ideal : TextFormattingMode.Display);
}

protected override void OnInitialized(EventArgs e)
{
// This is here just to make sure we can run commands in this event handler!
PoshConsole.ExecuteCommand("Write-Output $PSVersionTable");
base.OnInitialized(e);
}
}
}

0 comments on commit 9b52a39

Please sign in to comment.