@@ -31,43 +31,36 @@ internal class RunspaceProxy
31
31
public event RunspaceReadyHandler RunspaceReady ;
32
32
33
33
34
- private SyncEvents _syncEvents = new SyncEvents ( ) ;
35
- private readonly Runspace _runSpace ;
34
+ private readonly SyncEvents _syncEvents = new SyncEvents ( ) ;
35
+ private Runspace _runSpace ;
36
36
37
- public Pipeline _pipeline ;
37
+ private Pipeline _pipeline ;
38
38
39
39
public Command DefaultOutputCommand { get ; private set ; }
40
40
public Command ContentOutputCommand { get ; set ; }
41
41
42
42
43
- protected Queue < CallbackCommand > CommandQueue { get ; private set ; }
43
+ protected Queue < CallbackCommand > CommandQueue { get ; }
44
44
protected Thread WorkerThread ;
45
45
46
46
47
+ protected InitialSessionState InitialSessionState => _runSpace . InitialSessionState ;
47
48
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 ;
57
50
58
- public RunspaceStateInfo RunspaceStateInfo
59
- {
60
- get { return _runSpace . RunspaceStateInfo ; }
61
- }
51
+ protected RunspaceStateInfo RunspaceStateInfo => _runSpace . RunspaceStateInfo ;
62
52
63
- private Host _host ;
53
+ private readonly Host _host ;
64
54
65
55
public RunspaceProxy ( Host host )
66
56
{
67
57
_host = host ;
68
58
CommandQueue = new Queue < CallbackCommand > ( ) ;
59
+ }
69
60
61
+ public bool IsInitialized => _runSpace != null ;
70
62
63
+ public void Initialize ( ) {
71
64
// pre-create reusable commands
72
65
DefaultOutputCommand = new Command ( "Out-Default" ) ;
73
66
//// for now, merge the errors with the rest of the output
@@ -120,13 +113,13 @@ public RunspaceProxy(Host host)
120
113
var path = Path . GetDirectoryName ( poshModule . Location ) ;
121
114
iss . ImportPSModulesFromPath ( Path . Combine ( path , "Modules" ) ) ;
122
115
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" ) ) ) ;
124
117
//* %windir%\system32\WindowsPowerShell\v1.0\profile.ps1
125
118
// This profile applies to all users and all shells.
126
119
profile . Properties . Add ( new PSNoteProperty ( "AllUsersAllHosts" , Path . GetFullPath ( Path . Combine ( systemProfilePath , "Profile.ps1" ) ) ) ) ;
127
120
//* %windir%\system32\WindowsPowerShell\v1.0\PoshConsole_profile.ps1
128
121
// 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" ) ) ) ) ;
130
123
//* %UserProfile%\My Documents\WindowsPowerShell\profile.ps1
131
124
// This profile applies only to the current user, but affects all shells.
132
125
profile . Properties . Add ( new PSNoteProperty ( "CurrentUserAllHosts" , Path . GetFullPath ( Path . Combine ( currentUserProfilePath , "Profile.ps1" ) ) ) ) ;
@@ -143,7 +136,7 @@ public RunspaceProxy(Host host)
143
136
iss.Assemblies.Add(new SessionStateAssemblyEntry(sma.FullName, sma.CodeBase));
144
137
*/
145
138
146
- _runSpace = RunspaceFactory . CreateRunspace ( host , iss ) ;
139
+ _runSpace = RunspaceFactory . CreateRunspace ( _host , iss ) ;
147
140
148
141
// TODO: can we handle profiles this way?
149
142
/*
@@ -417,28 +410,35 @@ internal void ExecuteShutdownProfile(int exitCode)
417
410
/// </summary>
418
411
private void ExecuteStartupProfile ( )
419
412
{
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
+ }
425
435
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 } ) ;
434
437
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
+ }
442
442
}
443
443
}
444
444
0 commit comments