@@ -49,37 +49,28 @@ public sealed class EditorServicesLoader : IDisposable
49
49
/// </summary>
50
50
/// <param name="logger">The host logger to use.</param>
51
51
/// <param name="hostConfig">The host configuration to start editor services with.</param>
52
- /// <param name="sessionFileWriter">The session file writer to write the session file with.</param>
53
- /// <returns></returns>
54
- public static EditorServicesLoader Create (
55
- HostLogger logger ,
56
- EditorServicesConfig hostConfig ,
57
- ISessionFileWriter sessionFileWriter ) => Create ( logger , hostConfig , sessionFileWriter , loggersToUnsubscribe : null ) ;
58
-
59
- /// <summary>
60
- /// Create a new Editor Services loader.
61
- /// </summary>
62
- /// <param name="logger">The host logger to use.</param>
63
- /// <param name="hostConfig">The host configuration to start editor services with.</param>
64
- /// <param name="sessionFileWriter">The session file writer to write the session file with.</param>
52
+ /// <param name="sessionDetailsPath">Path to the session file to create on startup or startup failure.</param>
65
53
/// <param name="loggersToUnsubscribe">The loggers to unsubscribe form writing to the terminal.</param>
66
- /// <returns></returns>
67
54
public static EditorServicesLoader Create (
68
55
HostLogger logger ,
69
56
EditorServicesConfig hostConfig ,
70
- ISessionFileWriter sessionFileWriter ,
57
+ string sessionDetailsPath ,
71
58
IReadOnlyCollection < IDisposable > loggersToUnsubscribe )
72
59
{
73
- if ( logger == null )
60
+ if ( logger is null )
74
61
{
75
62
throw new ArgumentNullException ( nameof ( logger ) ) ;
76
63
}
77
64
78
- if ( hostConfig == null )
65
+ if ( hostConfig is null )
79
66
{
80
67
throw new ArgumentNullException ( nameof ( hostConfig ) ) ;
81
68
}
82
69
70
+ Version powerShellVersion = GetPSVersion ( ) ;
71
+ SessionFileWriter sessionFileWriter = new ( logger , sessionDetailsPath , powerShellVersion ) ;
72
+ logger . Log ( PsesLogLevel . Diagnostic , "Session file writer created" ) ;
73
+
83
74
#if CoreCLR
84
75
// In .NET Core, we add an event here to redirect dependency loading to the new AssemblyLoadContext we load PSES' dependencies into
85
76
logger . Log ( PsesLogLevel . Verbose , "Adding AssemblyResolve event handler for new AssemblyLoadContext dependency loading" ) ;
@@ -167,7 +158,7 @@ public static EditorServicesLoader Create(
167
158
} ;
168
159
#endif
169
160
170
- return new EditorServicesLoader ( logger , hostConfig , sessionFileWriter , loggersToUnsubscribe ) ;
161
+ return new EditorServicesLoader ( logger , hostConfig , sessionFileWriter , loggersToUnsubscribe , powerShellVersion ) ;
171
162
}
172
163
173
164
private readonly EditorServicesConfig _hostConfig ;
@@ -178,33 +169,38 @@ public static EditorServicesLoader Create(
178
169
179
170
private readonly IReadOnlyCollection < IDisposable > _loggersToUnsubscribe ;
180
171
172
+ private readonly Version _powerShellVersion ;
173
+
181
174
private EditorServicesRunner _editorServicesRunner ;
182
175
183
176
private EditorServicesLoader (
184
177
HostLogger logger ,
185
178
EditorServicesConfig hostConfig ,
186
179
ISessionFileWriter sessionFileWriter ,
187
- IReadOnlyCollection < IDisposable > loggersToUnsubscribe )
180
+ IReadOnlyCollection < IDisposable > loggersToUnsubscribe ,
181
+ Version powerShellVersion )
188
182
{
189
183
_logger = logger ;
190
184
_hostConfig = hostConfig ;
191
185
_sessionFileWriter = sessionFileWriter ;
192
186
_loggersToUnsubscribe = loggersToUnsubscribe ;
187
+ _powerShellVersion = powerShellVersion ;
193
188
}
194
189
195
190
/// <summary>
196
191
/// Load Editor Services and its dependencies in an isolated way and start it.
197
192
/// This method's returned task will end when Editor Services shuts down.
198
193
/// </summary>
199
- /// <returns></returns>
200
194
public Task LoadAndRunEditorServicesAsync ( )
201
195
{
202
196
// Log important host information here
203
197
LogHostInformation ( ) ;
204
198
199
+ CheckPowerShellVersion ( ) ;
200
+
205
201
#if ! CoreCLR
206
202
// Make sure the .NET Framework version supports .NET Standard 2.0
207
- CheckNetFxVersion ( ) ;
203
+ CheckDotNetVersion ( ) ;
208
204
#endif
209
205
210
206
// Add the bundled modules to the PSModulePath
@@ -241,10 +237,30 @@ private static void LoadEditorServices() =>
241
237
// The call within this method is therefore a total no-op
242
238
EditorServicesLoading . LoadEditorServicesForHost ( ) ;
243
239
240
+ private void CheckPowerShellVersion ( )
241
+ {
242
+ PSLanguageMode languageMode = Runspace . DefaultRunspace . SessionStateProxy . LanguageMode ;
243
+
244
+ _logger . Log ( PsesLogLevel . Verbose , $@ "
245
+ == PowerShell Details ==
246
+ - PowerShell version: { _powerShellVersion }
247
+ - Language mode: { languageMode }
248
+ " ) ;
249
+
250
+ if ( ( _powerShellVersion < new Version ( 5 , 1 ) )
251
+ || ( _powerShellVersion >= new Version ( 6 , 0 ) && _powerShellVersion < new Version ( 7 , 2 ) ) )
252
+ {
253
+ _logger . Log ( PsesLogLevel . Error , $ "PowerShell { _powerShellVersion } is not supported, please update!") ;
254
+ _sessionFileWriter . WriteSessionFailure ( "powerShellVersion" ) ;
255
+ }
256
+
257
+ // TODO: Check if language mode still matters for support.
258
+ }
259
+
244
260
#if ! CoreCLR
245
- private void CheckNetFxVersion ( )
261
+ private void CheckDotNetVersion ( )
246
262
{
247
- _logger . Log ( PsesLogLevel . Diagnostic , "Checking that .NET Framework version is at least 4.8" ) ;
263
+ _logger . Log ( PsesLogLevel . Verbose , "Checking that .NET Framework version is at least 4.8" ) ;
248
264
using RegistryKey key = Registry . LocalMachine . OpenSubKey ( @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" ) ;
249
265
object netFxValue = key ? . GetValue ( "Release" ) ;
250
266
if ( netFxValue == null || netFxValue is not int netFxVersion )
@@ -256,7 +272,8 @@ private void CheckNetFxVersion()
256
272
257
273
if ( netFxVersion < Net48Version )
258
274
{
259
- _logger . Log ( PsesLogLevel . Warning , $ ".NET Framework version { netFxVersion } lower than .NET 4.8. This runtime is not supported and you may experience errors. Please update your .NET runtime version.") ;
275
+ _logger . Log ( PsesLogLevel . error , $ ".NET Framework { netFxVersion } is out-of-date, please install at least 4.8: https://dotnet.microsoft.com/en-us/download/dotnet-framework") ;
276
+ _sessionFileWriter . WriteSessionFailure ( "dotNetVersion" ) ;
260
277
}
261
278
}
262
279
#endif
@@ -322,30 +339,6 @@ private void LogHostInformation()
322
339
- PowerShell output encoding: { GetPSOutputEncoding ( ) }
323
340
" ) ;
324
341
325
- LogPowerShellDetails ( ) ;
326
-
327
- LogOperatingSystemDetails ( ) ;
328
- }
329
-
330
- private static string GetPSOutputEncoding ( )
331
- {
332
- using SMA . PowerShell pwsh = SMA . PowerShell . Create ( ) ;
333
- return pwsh . AddScript ( "$OutputEncoding.EncodingName" , useLocalScope : true ) . Invoke < string > ( ) [ 0 ] ;
334
- }
335
-
336
- private void LogPowerShellDetails ( )
337
- {
338
- PSLanguageMode languageMode = Runspace . DefaultRunspace . SessionStateProxy . LanguageMode ;
339
-
340
- _logger . Log ( PsesLogLevel . Verbose , $@ "
341
- == PowerShell Details ==
342
- - PowerShell version: { GetPSVersion ( ) }
343
- - Language mode: { languageMode }
344
- " ) ;
345
- }
346
-
347
- private void LogOperatingSystemDetails ( )
348
- {
349
342
_logger . Log ( PsesLogLevel . Verbose , $@ "
350
343
== Environment Details ==
351
344
- OS description: { RuntimeInformation . OSDescription }
@@ -354,6 +347,12 @@ private void LogOperatingSystemDetails()
354
347
" ) ;
355
348
}
356
349
350
+ private static string GetPSOutputEncoding ( )
351
+ {
352
+ using SMA . PowerShell pwsh = SMA . PowerShell . Create ( ) ;
353
+ return pwsh . AddScript ( "$OutputEncoding.EncodingName" , useLocalScope : true ) . Invoke < string > ( ) [ 0 ] ;
354
+ }
355
+
357
356
// TODO: Deduplicate this with VersionUtils.
358
357
private static string GetOSArchitecture ( )
359
358
{
@@ -401,7 +400,7 @@ private void ValidateConfiguration()
401
400
}
402
401
}
403
402
404
- private static object GetPSVersion ( )
403
+ private static Version GetPSVersion ( )
405
404
{
406
405
// In order to read the $PSVersionTable variable,
407
406
// we are forced to create a new runspace to avoid concurrency issues,
@@ -412,7 +411,7 @@ private static object GetPSVersion()
412
411
return typeof ( PSObject ) . Assembly
413
412
. GetType ( "System.Management.Automation.PSVersionInfo" )
414
413
. GetMethod ( "get_PSVersion" , BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic )
415
- . Invoke ( null , new object [ 0 ] /* Cannot use Array.Empty, since it must work in net452 */ ) ;
414
+ . Invoke ( null , new object [ 0 ] /* Cannot use Array.Empty, since it must work in net452 */ ) as Version ;
416
415
#pragma warning restore CA1825
417
416
}
418
417
}
0 commit comments