Private/NewRemoteRunspace.ps1
using namespace System.Management.Automation.Runspaces function NewRemoteRunspace { [OutputType([System.Management.Automation.Runspaces.Runspace])] [CmdletBinding()] param( [int] $TargetProcessId, [string] $TargetAppDomain, [int] $Timeout = 10, [switch] $Prepare, [System.Management.Automation.PSCmdlet] $Cmdlet ) end { if (-not $TargetAppDomain) { # Sometimes when Get-EditorServicesProcess is ran before this, a process or two might be missing # for a short time while it's cleaning up. So we wait. $timeoutLoop = 0 while (-not ($pipeInfo = (GetNamedPipes) -match $TargetProcessId)) { Start-Sleep -Milliseconds 500 if (($timeoutLoop++) -eq 10) { $Cmdlet.ThrowTerminatingError( [ErrorRecord]::new( [ArgumentException]::new($Strings.CannotFindProcess), 'CannotFindProcess', [ErrorCategory]::InvalidArgument, $TargetProcessId)) } } $TargetAppDomain = $pipeInfo | GetPipeInfo | ForEach-Object AppDomain } $connection = [NamedPipeConnectionInfo]::new($TargetProcessId, $TargetAppDomain, $Timeout) $typeTable = [TypeTable]::LoadDefaultTypeFiles() $newRunspace = [runspacefactory]::CreateRunspace($connection, $host, $typeTable) if (-not $newRunspace) { $Cmdlet.ThrowTerminatingError( [ErrorRecord]::new( [ArgumentException]::new($Strings.CannotFindProcess), 'CannotFindProcess', [ErrorCategory]::InvalidArgument, $TargetProcessId)) } $null = $newRunspace.GetType().GetProperty('ShouldCloseOnPop', 60).SetValue($newRunspace, $true) if ($Prepare.IsPresent) { try { $newRunspace.Open() $psPrepInstance = [powershell]::Create(). AddScript(' $global:psEditorRunspace = Get-Runspace 2 $global:psEditor = $psEditorRunspace.SessionStateProxy.PSVariable.GetValue("psEditor") Set-Location $psEditor.Workspace.Path Import-Module (Join-Path ($psEditorRunspace. SessionStateProxy. InvokeCommand. GetCommand("Find-Ast", "Function"). Module. ModuleBase) "PowerShellEditorServices.Commands.psd1") ') $psPrepInstance.Runspace = $newRunspace $null = $psPrepInstance.Invoke() } catch { $newRunspace.Close() $newRunspace.Dispose() } finally { if ($psPrepInstance) { $psPrepInstance.Dispose() } } } # If the pipe gets parsed wrong the runspace can come out broken. Also if cleanup wasn't done # currently after exiting the runspace. if ('Broken' -eq $newRunspace.State) { $Cmdlet.ThrowTerminatingError( [ErrorRecord]::new( [RuntimeException]::new($Strings.InvalidRunspaceState, $newRunspace.State.Reason), 'InvalidRunspaceState', [ErrorCategory]::InvalidArgument, $TargetProcessId)) } return $newRunspace } } |