@@ -17,12 +17,17 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShellContext
1717
1818 internal class PSReadLinePromptContext : IPromptContext
1919 {
20+ private static readonly string _psReadLineModulePath = Path . Combine (
21+ Path . GetDirectoryName ( typeof ( PSReadLinePromptContext ) . Assembly . Location ) ,
22+ ".." ,
23+ ".." ,
24+ ".." ,
25+ "PSReadLine" ) ;
26+
2027 private static readonly Lazy < CmdletInfo > s_lazyInvokeReadLineForEditorServicesCmdletInfo = new Lazy < CmdletInfo > ( ( ) =>
2128 {
22- var allAssemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
23- var assemblies = allAssemblies . FirstOrDefault ( a => a . FullName . Contains ( "Microsoft.PowerShell.EditorServices" ) ) ;
24- var type = assemblies ? . ExportedTypes ? . FirstOrDefault ( a => a . Name == "InvokeReadLineForEditorServicesCommand" ) ;
25- return new CmdletInfo ( "__Invoke-ReadLineForEditorServices" , type ?? typeof ( PSCmdlet ) ) ;
29+ var type = Type . GetType ( "Microsoft.PowerShell.EditorServices.Commands.InvokeReadLineForEditorServicesCommand, Microsoft.PowerShell.EditorServices.Hosting" ) ;
30+ return new CmdletInfo ( "__Invoke-ReadLineForEditorServices" , type ) ;
2631 } ) ;
2732
2833 private static ExecutionOptions s_psrlExecutionOptions = new ExecutionOptions
@@ -66,35 +71,40 @@ internal PSReadLinePromptContext(
6671
6772 internal static bool TryGetPSReadLineProxy (
6873 ILogger logger ,
74+ Runspace runspace ,
6975 out PSReadLineProxy readLineProxy )
7076 {
7177 readLineProxy = null ;
7278 logger . LogTrace ( "Attempting to load PSReadLine" ) ;
73- var psReadLineAssembly = AppDomain . CurrentDomain . GetAssemblies ( ) . FirstOrDefault ( a => a . FullName . Contains ( "Microsoft.PowerShell.PSReadLine2" ) ) ;
74- if ( psReadLineAssembly is null )
75- {
76- logger . LogWarning ( "Microsoft.PowerShell.PSReadLine2 not found in loaded assemblies" ) ;
77- return false ;
78- }
79- var psReadLineType = psReadLineAssembly ? . ExportedTypes ? . FirstOrDefault ( a => a . Name == "PSConsoleReadLine" ) ;
80-
81- if ( psReadLineType == null )
82- {
83- logger . LogWarning ( "PSConsoleReadLine type not found in Microsoft.PowerShell.PSReadLine2" ) ;
84- return false ;
85- }
86-
87- try
88- {
89- readLineProxy = new PSReadLineProxy ( psReadLineType , logger ) ;
90- }
91- catch ( InvalidOperationException e )
79+ using ( var pwsh = PowerShell . Create ( ) )
9280 {
93- // The Type we got back from PowerShell doesn't have the members we expected.
94- // Could be an older version, a custom build, or something a newer version with
95- // breaking changes.
96- logger . LogWarning ( "PSReadLine unable to be loaded: {Reason}" , e ) ;
97- return false ;
81+ pwsh . Runspace = runspace ;
82+ var psReadLineType = pwsh
83+ . AddCommand ( "Microsoft.PowerShell.Core\\ Import-Module" )
84+ . AddParameter ( "Name" , _psReadLineModulePath )
85+ . AddStatement ( )
86+ . AddScript ( "[Microsoft.PowerShell.PSConsoleReadLine]" , true )
87+ . Invoke < Type > ( )
88+ . FirstOrDefault ( ) ;
89+
90+ if ( psReadLineType == null )
91+ {
92+ logger . LogWarning ( "PSReadLine unable to be loaded: {Reason}" , pwsh . HadErrors ? pwsh . Streams . Error [ 0 ] . ToString ( ) : "<Unknown reason>" ) ;
93+ return false ;
94+ }
95+
96+ try
97+ {
98+ readLineProxy = new PSReadLineProxy ( psReadLineType , logger ) ;
99+ }
100+ catch ( InvalidOperationException e )
101+ {
102+ // The Type we got back from PowerShell doesn't have the members we expected.
103+ // Could be an older version, a custom build, or something a newer version with
104+ // breaking changes.
105+ logger . LogWarning ( "PSReadLine unable to be loaded: {Reason}" , e ) ;
106+ return false ;
107+ }
98108 }
99109
100110 return true ;
@@ -104,12 +114,12 @@ public async Task<string> InvokeReadLineAsync(bool isCommandLine, CancellationTo
104114 {
105115 _readLineCancellationSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
106116 var localTokenSource = _readLineCancellationSource ;
107- if ( localTokenSource . Token . IsCancellationRequested )
117+ if ( localTokenSource . Token . IsCancellationRequested )
108118 {
109119 throw new TaskCanceledException ( ) ;
110120 }
111121
112- if ( ! isCommandLine )
122+ if ( ! isCommandLine )
113123 {
114124 return await _consoleReadLine . InvokeLegacyReadLineAsync (
115125 isCommandLine : false ,
@@ -134,7 +144,7 @@ public async Task<string> InvokeReadLineAsync(bool isCommandLine, CancellationTo
134144
135145 public void AbortReadLine ( )
136146 {
137- if ( _readLineCancellationSource == null )
147+ if ( _readLineCancellationSource == null )
138148 {
139149 return ;
140150 }
@@ -146,7 +156,7 @@ public void AbortReadLine()
146156
147157 public async Task AbortReadLineAsync ( )
148158 {
149- if ( _readLineCancellationSource == null )
159+ if ( _readLineCancellationSource == null )
150160 {
151161 return ;
152162 }
@@ -158,13 +168,13 @@ public async Task AbortReadLineAsync()
158168
159169 public void WaitForReadLineExit ( )
160170 {
161- using ( _promptNest . GetRunspaceHandle ( CancellationToken . None , isReadLine : true ) )
171+ using ( _promptNest . GetRunspaceHandle ( CancellationToken . None , isReadLine : true ) )
162172 { }
163173 }
164174
165175 public async Task WaitForReadLineExitAsync ( )
166176 {
167- using ( await _promptNest . GetRunspaceHandleAsync ( CancellationToken . None , isReadLine : true ) . ConfigureAwait ( false ) )
177+ using ( await _promptNest . GetRunspaceHandleAsync ( CancellationToken . None , isReadLine : true ) . ConfigureAwait ( false ) )
168178 { }
169179 }
170180
0 commit comments