@@ -17,12 +17,17 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShellContext
17
17
18
18
internal class PSReadLinePromptContext : IPromptContext
19
19
{
20
+ private static readonly string _psReadLineModulePath = Path . Combine (
21
+ Path . GetDirectoryName ( typeof ( PSReadLinePromptContext ) . Assembly . Location ) ,
22
+ ".." ,
23
+ ".." ,
24
+ ".." ,
25
+ "PSReadLine" ) ;
26
+
20
27
private static readonly Lazy < CmdletInfo > s_lazyInvokeReadLineForEditorServicesCmdletInfo = new Lazy < CmdletInfo > ( ( ) =>
21
28
{
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 ) ;
26
31
} ) ;
27
32
28
33
private static ExecutionOptions s_psrlExecutionOptions = new ExecutionOptions
@@ -66,35 +71,40 @@ internal PSReadLinePromptContext(
66
71
67
72
internal static bool TryGetPSReadLineProxy (
68
73
ILogger logger ,
74
+ Runspace runspace ,
69
75
out PSReadLineProxy readLineProxy )
70
76
{
71
77
readLineProxy = null ;
72
78
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 ( ) )
92
80
{
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
+ }
98
108
}
99
109
100
110
return true ;
@@ -104,12 +114,12 @@ public async Task<string> InvokeReadLineAsync(bool isCommandLine, CancellationTo
104
114
{
105
115
_readLineCancellationSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
106
116
var localTokenSource = _readLineCancellationSource ;
107
- if ( localTokenSource . Token . IsCancellationRequested )
117
+ if ( localTokenSource . Token . IsCancellationRequested )
108
118
{
109
119
throw new TaskCanceledException ( ) ;
110
120
}
111
121
112
- if ( ! isCommandLine )
122
+ if ( ! isCommandLine )
113
123
{
114
124
return await _consoleReadLine . InvokeLegacyReadLineAsync (
115
125
isCommandLine : false ,
@@ -134,7 +144,7 @@ public async Task<string> InvokeReadLineAsync(bool isCommandLine, CancellationTo
134
144
135
145
public void AbortReadLine ( )
136
146
{
137
- if ( _readLineCancellationSource == null )
147
+ if ( _readLineCancellationSource == null )
138
148
{
139
149
return ;
140
150
}
@@ -146,7 +156,7 @@ public void AbortReadLine()
146
156
147
157
public async Task AbortReadLineAsync ( )
148
158
{
149
- if ( _readLineCancellationSource == null )
159
+ if ( _readLineCancellationSource == null )
150
160
{
151
161
return ;
152
162
}
@@ -158,13 +168,13 @@ public async Task AbortReadLineAsync()
158
168
159
169
public void WaitForReadLineExit ( )
160
170
{
161
- using ( _promptNest . GetRunspaceHandle ( CancellationToken . None , isReadLine : true ) )
171
+ using ( _promptNest . GetRunspaceHandle ( CancellationToken . None , isReadLine : true ) )
162
172
{ }
163
173
}
164
174
165
175
public async Task WaitForReadLineExitAsync ( )
166
176
{
167
- using ( await _promptNest . GetRunspaceHandleAsync ( CancellationToken . None , isReadLine : true ) . ConfigureAwait ( false ) )
177
+ using ( await _promptNest . GetRunspaceHandleAsync ( CancellationToken . None , isReadLine : true ) . ConfigureAwait ( false ) )
168
178
{ }
169
179
}
170
180
0 commit comments