@@ -37,6 +37,7 @@ public class PowerShellContext : IDisposable
37
37
private bool ownsInitialRunspace ;
38
38
private Runspace initialRunspace ;
39
39
private Runspace currentRunspace ;
40
+ private ProfilePaths profilePaths ;
40
41
private ConsoleServicePSHost psHost ;
41
42
private InitialSessionState initialSessionState ;
42
43
private IVersionSpecificOperations versionSpecificOperations ;
@@ -104,7 +105,21 @@ internal IConsoleHost ConsoleHost
104
105
/// Initializes a new instance of the PowerShellContext class and
105
106
/// opens a runspace to be used for the session.
106
107
/// </summary>
107
- public PowerShellContext ( )
108
+ public PowerShellContext ( ) : this ( null )
109
+ {
110
+ }
111
+
112
+ /// <summary>
113
+ /// Initializes a new instance of the PowerShellContext class and
114
+ /// opens a runspace to be used for the session.
115
+ /// </summary>
116
+ /// <param name="hostProfileId">
117
+ /// The identifier of the PowerShell host to use for its profile path.
118
+ /// loaded. Used to resolve a profile path of the form 'X_profile.ps1'
119
+ /// where 'X' represents the value of hostProfileId. If null, a default
120
+ /// will be used.
121
+ /// </param>
122
+ public PowerShellContext ( string hostProfileId )
108
123
{
109
124
this . psHost = new ConsoleServicePSHost ( ) ;
110
125
this . initialSessionState = InitialSessionState . CreateDefault2 ( ) ;
@@ -116,7 +131,7 @@ public PowerShellContext()
116
131
117
132
this . ownsInitialRunspace = true ;
118
133
119
- this . Initialize ( runspace ) ;
134
+ this . Initialize ( hostProfileId , runspace ) ;
120
135
121
136
// Use reflection to execute ConsoleVisibility.AlwaysCaptureApplicationIO = true;
122
137
Type consoleVisibilityType =
@@ -142,12 +157,23 @@ public PowerShellContext()
142
157
/// an existing runspace for the session.
143
158
/// </summary>
144
159
/// <param name="initialRunspace"></param>
145
- public PowerShellContext ( Runspace initialRunspace )
160
+ /// <param name="hostProfileId">
161
+ /// The identifier of the PowerShell host to use for its profile path.
162
+ /// loaded. Used to resolve a profile path of the form 'X_profile.ps1'
163
+ /// where 'X' represents the value of hostProfileId. If null, a default
164
+ /// will be used.
165
+ /// </param>
166
+ public PowerShellContext ( string hostProfileId , Runspace initialRunspace )
146
167
{
147
- this . Initialize ( initialRunspace ) ;
168
+ this . Initialize ( hostProfileId , initialRunspace ) ;
148
169
}
149
170
150
171
private void Initialize ( Runspace initialRunspace )
172
+ {
173
+ this . Initialize ( null , initialRunspace ) ;
174
+ }
175
+
176
+ private void Initialize ( string hostProfileId , Runspace initialRunspace )
151
177
{
152
178
Validate . IsNotNull ( "initialRunspace" , initialRunspace ) ;
153
179
@@ -160,7 +186,6 @@ private void Initialize(Runspace initialRunspace)
160
186
this . currentRunspace . Debugger . DebuggerStop += OnDebuggerStop ;
161
187
162
188
this . powerShell = PowerShell . Create ( ) ;
163
- this . powerShell . InvocationStateChanged += powerShell_InvocationStateChanged ;
164
189
this . powerShell . Runspace = this . currentRunspace ;
165
190
166
191
// TODO: Should this be configurable?
@@ -199,6 +224,14 @@ private void Initialize(Runspace initialRunspace)
199
224
this . versionSpecificOperations . ConfigureDebugger (
200
225
this . currentRunspace ) ;
201
226
227
+ // Set the $profile variable in the runspace
228
+ this . profilePaths =
229
+ this . SetProfileVariableInCurrentRunspace (
230
+ hostProfileId ?? ProfilePaths . DefaultHostProfileId ) ;
231
+
232
+ // Now that initialization is complete we can watch for InvocationStateChanged
233
+ this . powerShell . InvocationStateChanged += powerShell_InvocationStateChanged ;
234
+
202
235
this . SessionState = PowerShellContextState . Ready ;
203
236
204
237
// Now that the runspace is ready, enqueue it for first use
@@ -493,6 +526,24 @@ public async Task ExecuteScriptAtPath(string scriptPath, string arguments = null
493
526
await this . ExecuteCommand < object > ( command , true ) ;
494
527
}
495
528
529
+ /// <summary>
530
+ /// Loads PowerShell profiles for the host from the
531
+ /// standard system locations. Only the profile paths which
532
+ /// exist are loaded.
533
+ /// </summary>
534
+ /// <returns>A Task that can be awaited for completion.</returns>
535
+ public async Task LoadProfilesForHost ( )
536
+ {
537
+ // Load any of the profile paths that exist
538
+ PSCommand command = null ;
539
+ foreach ( var profilePath in this . profilePaths . GetLoadableProfilePaths ( ) )
540
+ {
541
+ command = new PSCommand ( ) ;
542
+ command . AddCommand ( profilePath , false ) ;
543
+ await this . ExecuteCommand ( command ) ;
544
+ }
545
+ }
546
+
496
547
/// <summary>
497
548
/// Causes the current execution to be aborted no matter what state
498
549
/// it is currently in.
@@ -970,6 +1021,56 @@ private void WritePromptWithNestedPipeline()
970
1021
} ) ;
971
1022
}
972
1023
}
1024
+
1025
+ private ProfilePaths SetProfileVariableInCurrentRunspace ( string hostProfileId )
1026
+ {
1027
+ // Get the profile paths for the host name
1028
+ ProfilePaths profilePaths =
1029
+ new ProfilePaths (
1030
+ hostProfileId ,
1031
+ this . currentRunspace ) ;
1032
+
1033
+ // Create the $profile variable
1034
+ PSObject profile = new PSObject ( profilePaths . CurrentUserCurrentHost ) ;
1035
+
1036
+ profile . Members . Add (
1037
+ new PSNoteProperty (
1038
+ nameof ( profilePaths . AllUsersAllHosts ) ,
1039
+ profilePaths . AllUsersAllHosts ) ) ;
1040
+
1041
+ profile . Members . Add (
1042
+ new PSNoteProperty (
1043
+ nameof ( profilePaths . AllUsersCurrentHost ) ,
1044
+ profilePaths . AllUsersCurrentHost ) ) ;
1045
+
1046
+ profile . Members . Add (
1047
+ new PSNoteProperty (
1048
+ nameof ( profilePaths . CurrentUserAllHosts ) ,
1049
+ profilePaths . CurrentUserAllHosts ) ) ;
1050
+
1051
+ profile . Members . Add (
1052
+ new PSNoteProperty (
1053
+ nameof ( profilePaths . CurrentUserCurrentHost ) ,
1054
+ profilePaths . CurrentUserCurrentHost ) ) ;
1055
+
1056
+ Logger . Write (
1057
+ LogLevel . Verbose ,
1058
+ string . Format (
1059
+ "Setting $profile variable in runspace. Current user host profile path: {0}" ,
1060
+ profilePaths . CurrentUserCurrentHost ) ) ;
1061
+
1062
+ // Set the variable in the runspace
1063
+ this . powerShell . Commands . Clear ( ) ;
1064
+ this . powerShell
1065
+ . AddCommand ( "Set-Variable" )
1066
+ . AddParameter ( "Name" , "profile" )
1067
+ . AddParameter ( "Value" , profile )
1068
+ . AddParameter ( "Option" , "None" ) ;
1069
+ this . powerShell . Invoke ( ) ;
1070
+ this . powerShell . Commands . Clear ( ) ;
1071
+
1072
+ return profilePaths ;
1073
+ }
973
1074
974
1075
#endregion
975
1076
0 commit comments