Skip to content

Commit 591c77e

Browse files
Make alias discovery possible on idle
The use of `Runspace.SessionStateProxy` while the pipeline thread is busy (even if you are **on** the pipeline thread) results in an exception. This also allows us to cancel `GetAliasesAsync`.
1 parent a991beb commit 591c77e

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

src/PowerShellEditorServices/Services/PowerShell/Utility/CommandHelpers.cs

+18-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility
1616
/// </summary>
1717
internal static class CommandHelpers
1818
{
19+
public record struct AliasMap(
20+
Dictionary<string, List<string>> CmdletToAliases,
21+
Dictionary<string, string> AliasToCmdlets);
22+
1923
private static readonly HashSet<string> s_nounExclusionList = new()
2024
{
2125
// PowerShellGet v2 nouns
@@ -180,19 +184,21 @@ not CommandTypes.Function and
180184
/// Gets all aliases found in the runspace
181185
/// </summary>
182186
/// <param name="executionService"></param>
183-
public static async Task<(Dictionary<string, List<string>>, Dictionary<string, string>)> GetAliasesAsync(IInternalPowerShellExecutionService executionService)
187+
/// <param name="cancellationToken"></param>
188+
public static async Task<AliasMap> GetAliasesAsync(
189+
IInternalPowerShellExecutionService executionService,
190+
CancellationToken cancellationToken = default)
184191
{
185192
Validate.IsNotNull(nameof(executionService), executionService);
186193

187-
IEnumerable<CommandInfo> aliases = await executionService.ExecuteDelegateAsync(
188-
nameof(GetAliasesAsync),
189-
executionOptions: null,
190-
(pwsh, _) =>
191-
{
192-
CommandInvocationIntrinsics invokeCommand = pwsh.Runspace.SessionStateProxy.InvokeCommand;
193-
return invokeCommand.GetCommands("*", CommandTypes.Alias, nameIsPattern: true);
194-
},
195-
CancellationToken.None).ConfigureAwait(false);
194+
// Need to execute a PSCommand here as Runspace.SessionStateProxy cannot be used from
195+
// our PSRL on idle handler.
196+
IReadOnlyList<CommandInfo> aliases = await executionService.ExecutePSCommandAsync<CommandInfo>(
197+
new PSCommand()
198+
.AddCommand("Microsoft.PowerShell.Core\\Get-Command")
199+
.AddParameter("ListImported", true)
200+
.AddParameter("CommandType", CommandTypes.Alias),
201+
cancellationToken).ConfigureAwait(false);
196202

197203
foreach (AliasInfo aliasInfo in aliases)
198204
{
@@ -206,7 +212,8 @@ not CommandTypes.Function and
206212
s_aliasToCmdletCache.TryAdd(aliasInfo.Name, aliasInfo.Definition);
207213
}
208214

209-
return (new Dictionary<string, List<string>>(s_cmdletToAliasCache),
215+
return new AliasMap(
216+
new Dictionary<string, List<string>>(s_cmdletToAliasCache),
210217
new Dictionary<string, string>(s_aliasToCmdletCache));
211218
}
212219
}

0 commit comments

Comments
 (0)