Skip to content

Commit 7067575

Browse files
Fix startup bug when zero profiles are present (#1807)
The service would fail to fully start if zero profiles were present, because that meant we attempted to invoke an empty command, which then threw `PSInvalidOperationException: No commands are specified`. This wasn't caught by our task executor, since it happened in a delegate which directly invoked the command.
1 parent 1081868 commit 7067575

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ public PsesInternalHost(
113113
_cancellationContext = new CancellationContext();
114114

115115
// Default stack size on .NET Framework is 524288 (512KB) (as reported by GetProcessDefaultStackSize)
116-
// this leaves very little room in the stack. Windows PowerShell internally sets the value based on
117-
// PipelineMaxStackSizeMB as seen here: https://github.com/PowerShell/PowerShell/issues/1187,
116+
// this leaves very little room in the stack. Windows PowerShell internally sets the value based on
117+
// PipelineMaxStackSizeMB as seen here: https://github.com/PowerShell/PowerShell/issues/1187,
118118
// which has default of 10 and multiplies that by 1_000_000, so the default stack size is
119-
// 10_000_000 (~10MB) when starting in normal console host.
119+
// 10_000_000 (~10MB) when starting in normal console host.
120120
//
121-
// For PS7 the value is ignored by .NET because settings the stack size is not supported, but we can
121+
// For PS7 the value is ignored by .NET because settings the stack size is not supported, but we can
122122
// still provide 0, which means fallback to the default in both .NET and .NET Framework.
123123
int maxStackSize = VersionUtils.IsPS5 ? 10_000_000 : 0;
124124
_pipelineThread = new Thread(Run, maxStackSize)
@@ -433,7 +433,7 @@ internal Task LoadHostProfilesAsync(CancellationToken cancellationToken)
433433
// NOTE: This is a special task run on startup!
434434
return ExecuteDelegateAsync(
435435
"LoadProfiles",
436-
new PowerShellExecutionOptions { ThrowOnError = false },
436+
executionOptions: null,
437437
(pwsh, _) => pwsh.LoadProfiles(_hostInfo.ProfilePaths),
438438
cancellationToken);
439439
}

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
// Licensed under the MIT License.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Collections.ObjectModel;
67
using System.Reflection;
78
using System.Text;
89
using Microsoft.Extensions.Logging;
910
using Microsoft.PowerShell.EditorServices.Hosting;
1011
using Microsoft.PowerShell.EditorServices.Utility;
11-
using System.Collections.Generic;
1212

1313
namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility
1414
{
@@ -211,7 +211,13 @@ public static void LoadProfiles(this PowerShell pwsh, ProfilePathInfo profilePat
211211
// NOTE: This must be set before the profiles are loaded.
212212
pwsh.Runspace.SessionStateProxy.SetVariable("PROFILE", profileVariable);
213213

214-
pwsh.InvokeCommand(psCommand);
214+
// NOTE: Because it's possible there are no profiles defined, we might have an empty
215+
// command. Since this is being executed directly, we can't rely on `ThrowOnError =
216+
// false` to avoid an exception here. Instead, we must just not execute it.
217+
if (psCommand.Commands.Count > 0)
218+
{
219+
pwsh.InvokeCommand(psCommand);
220+
}
215221
}
216222

217223
public static void ImportModule(this PowerShell pwsh, string moduleNameOrPath)

src/PowerShellEditorServices/Utility/PSCommandExtensions.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,7 @@ public static PSCommand AddProfileLoadIfExists(this PSCommand psCommand, PSObjec
7777

7878
if (File.Exists(profilePath))
7979
{
80-
psCommand
81-
.AddCommand(profilePath, useLocalScope: false)
82-
.AddOutputCommand()
83-
.AddStatement();
80+
psCommand.AddCommand(profilePath, useLocalScope: false).AddOutputCommand().AddStatement();
8481
}
8582

8683
return psCommand;

0 commit comments

Comments
 (0)