Skip to content

Commit 9b52a39

Browse files
committed
Fix initialization ...
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
1 parent 7cbd492 commit 9b52a39

File tree

3 files changed

+63
-53
lines changed

3 files changed

+63
-53
lines changed

PoshCode.PoshConsole/PoshConsole.cs

+13-11
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,9 @@ protected override void OnInitialized(EventArgs e)
7979

8080
Loaded += (sender, ignored) =>
8181
{
82-
if (Runner == null)
82+
if (!Runner.IsInitialized)
8383
{
84-
Runner = new RunspaceProxy(_host);
85-
Runner.RunspaceReady += (source, args) => Dispatcher.BeginInvoke((Action) (() =>
86-
{
87-
CommandBox.IsEnabled = true;
88-
ExecutePromptFunction(null, PipelineState.Completed);
89-
}));
90-
91-
// TODO: Improve this interface
92-
Expander.TabComplete = Runner.CompleteInput;
84+
Runner.Initialize();
9385
}
9486
};
9587
}
@@ -226,7 +218,17 @@ public PoshConsole()
226218
str.Append(obj);
227219
}
228220
Prompt(str.ToString());
229-
}) { DefaultOutput = false, Secret = true };
221+
}) { DefaultOutput = false, Secret = true };
222+
223+
Runner = new RunspaceProxy(_host);
224+
Runner.RunspaceReady += (source, args) => Dispatcher.BeginInvoke((Action)(() =>
225+
{
226+
CommandBox.IsEnabled = true;
227+
ExecutePromptFunction(null, PipelineState.Completed);
228+
}));
229+
230+
// TODO: Improve this interface
231+
Expander.TabComplete = Runner.CompleteInput;
230232
}
231233

232234
public Command DefaultOutputCommand { get; set; }

PoshCode.PoshConsole/PowerShell/RunspaceProxy.cs

+41-41
Original file line numberDiff line numberDiff line change
@@ -31,43 +31,36 @@ internal class RunspaceProxy
3131
public event RunspaceReadyHandler RunspaceReady;
3232

3333

34-
private SyncEvents _syncEvents = new SyncEvents();
35-
private readonly Runspace _runSpace;
34+
private readonly SyncEvents _syncEvents = new SyncEvents();
35+
private Runspace _runSpace;
3636

37-
public Pipeline _pipeline;
37+
private Pipeline _pipeline;
3838

3939
public Command DefaultOutputCommand { get; private set; }
4040
public Command ContentOutputCommand { get; set; }
4141

4242

43-
protected Queue<CallbackCommand> CommandQueue { get; private set; }
43+
protected Queue<CallbackCommand> CommandQueue { get; }
4444
protected Thread WorkerThread;
4545

4646

47+
protected InitialSessionState InitialSessionState => _runSpace.InitialSessionState;
4748

48-
public InitialSessionState InitialSessionState
49-
{
50-
get { return _runSpace.InitialSessionState; }
51-
}
52-
53-
public RunspaceConfiguration RunspaceConfiguration
54-
{
55-
get { return _runSpace.RunspaceConfiguration; }
56-
}
49+
protected RunspaceConfiguration RunspaceConfiguration => _runSpace.RunspaceConfiguration;
5750

58-
public RunspaceStateInfo RunspaceStateInfo
59-
{
60-
get { return _runSpace.RunspaceStateInfo; }
61-
}
51+
protected RunspaceStateInfo RunspaceStateInfo => _runSpace.RunspaceStateInfo;
6252

63-
private Host _host;
53+
private readonly Host _host;
6454

6555
public RunspaceProxy(Host host)
6656
{
6757
_host = host;
6858
CommandQueue = new Queue<CallbackCommand>();
59+
}
6960

61+
public bool IsInitialized => _runSpace != null;
7062

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

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

146-
_runSpace = RunspaceFactory.CreateRunspace(host, iss);
139+
_runSpace = RunspaceFactory.CreateRunspace(_host, iss);
147140

148141
// TODO: can we handle profiles this way?
149142
/*
@@ -417,28 +410,35 @@ internal void ExecuteShutdownProfile(int exitCode)
417410
/// </summary>
418411
private void ExecuteStartupProfile()
419412
{
420-
CommandQueue.Clear();
421-
422-
Enqueue(new CallbackCommand(new[] { new Command(Resources.Prompt, true, true) }, null) { Secret = true });
423-
424-
Enqueue(new CallbackCommand(new[] { new Command(Resources.TabExpansion2, true, true) }, null) { Secret = true });
413+
// we're going to ensure the startup profile goes _first_
414+
lock (((ICollection) CommandQueue).SyncRoot)
415+
{
416+
CallbackCommand[] commands = new CallbackCommand[CommandQueue.Count];
417+
CommandQueue.CopyTo(commands, 0);
418+
CommandQueue.Clear();
419+
420+
var existing = (
421+
from profileVariable in InitialSessionState.Variables["profile"]
422+
from pathProperty in ((PSObject) profileVariable.Value).Properties.Match("*Host*", PSMemberTypes.NoteProperty)
423+
where File.Exists(pathProperty.Value.ToString())
424+
select pathProperty.Value.ToString()
425+
).Select(path => new Command(path, false, true)).ToArray();
426+
// This might be nice to have too (in case anyone was using it):
427+
_runSpace.SessionStateProxy.SetVariable("profiles", existing.ToArray());
428+
429+
if (existing.Any())
430+
{
431+
CommandQueue.Enqueue(new CallbackCommand(existing,
432+
ignored => RunspaceReady(this, _runSpace.RunspaceStateInfo.State)) {Secret = true});
433+
// this is super important
434+
}
425435

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

435-
if (existing.Any())
436-
{
437-
Enqueue(new CallbackCommand( existing, ignored => RunspaceReady(this, _runSpace.RunspaceStateInfo.State)) { Secret = true }); // this is super important
438-
}
439-
else
440-
{
441-
Enqueue(new CallbackCommand( "New-Paragraph", ignored => RunspaceReady(this, _runSpace.RunspaceStateInfo.State)) { Secret = true }); // this is super important
438+
foreach (var command in commands)
439+
{
440+
CommandQueue.Enqueue(command);
441+
}
442442
}
443443
}
444444

PoshConsole.Demo/MainWindow.xaml.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Windows;
1+
using System;
2+
using System.Windows;
23
using System.Windows.Media;
34
using Fluent;
45

@@ -18,5 +19,12 @@ private void ZoomSlider_OnValueChanged(object sender, RoutedPropertyChangedEvent
1819
{
1920
TextOptions.SetTextFormattingMode(this, e.NewValue > 1.0 ? TextFormattingMode.Ideal : TextFormattingMode.Display);
2021
}
22+
23+
protected override void OnInitialized(EventArgs e)
24+
{
25+
// This is here just to make sure we can run commands in this event handler!
26+
PoshConsole.ExecuteCommand("Write-Output $PSVersionTable");
27+
base.OnInitialized(e);
28+
}
2129
}
2230
}

0 commit comments

Comments
 (0)