diff --git a/src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs b/src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs index 5e9a84f3d..499757faa 100644 --- a/src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs +++ b/src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs @@ -475,8 +475,18 @@ private void Run() (PowerShell pwsh, RunspaceInfo localRunspaceInfo, EngineIntrinsics engineIntrinsics) = CreateInitialPowerShellSession(); _mainRunspaceEngineIntrinsics = engineIntrinsics; _localComputerName = localRunspaceInfo.SessionDetails.ComputerName; - _runspaceStack.Push(new RunspaceFrame(pwsh.Runspace, localRunspaceInfo)); - PushPowerShellAndRunLoop(pwsh, PowerShellFrameType.Normal | PowerShellFrameType.Repl, localRunspaceInfo); + + // NOTE: In order to support running events registered to PowerShell's OnIdle + // handler, we have to have our top-level PowerShell instance be nested (otherwise + // we get a PSInvalidOperationException because pipelines cannot be run + // concurrently). Specifically this bug cropped up when a profile loaded code which + // registered (and subsequently ran) on the OnIdle handler since it was hitting the + // non-nested PowerShell instance. So now we just start with a nested instance. + // While the PowerShell object is nested, as a frame type, this is our top-level + // frame and therefore NOT nested in that sense. + PowerShell nestedPwsh = CreateNestedPowerShell(localRunspaceInfo); + _runspaceStack.Push(new RunspaceFrame(nestedPwsh.Runspace, localRunspaceInfo)); + PushPowerShellAndRunLoop(nestedPwsh, PowerShellFrameType.Normal | PowerShellFrameType.Repl, localRunspaceInfo); } catch (Exception e) { @@ -964,9 +974,7 @@ private static PowerShell CreateNestedPowerShell(RunspaceInfo currentRunspace) // PowerShell.CreateNestedPowerShell() sets IsNested but not IsChild // This means it throws due to the parent pipeline not running... // So we must use the RunspaceMode.CurrentRunspace option on PowerShell.Create() instead - PowerShell pwsh = PowerShell.Create(RunspaceMode.CurrentRunspace); - pwsh.Runspace.ThreadOptions = PSThreadOptions.UseCurrentThread; - return pwsh; + return PowerShell.Create(RunspaceMode.CurrentRunspace); } private static PowerShell CreatePowerShellForRunspace(Runspace runspace)