Invoke-Background.ps1
function Invoke-Background { [CmdletBinding(DefaultParameterSetName='ScriptBlock')] param( # A Script block to run in the background. # To pass parameters to this script block, add a param() statement [Parameter(Mandatory=$true,ParameterSetName='ScriptBlock',Position=0)] [ScriptBlock]$ScriptBlock, # Invoke a command in the background [Parameter(Mandatory=$true,ParameterSetName='Command',Position=0)] [string] $Command, [Hashtable]$Parameter, $control = $this, [ValidateScript({ if ($_.RunspaceStateInfo.State -ne 'Opened') { throw 'If a runspace is provided, it must be opened' } return $true })] [Management.Automation.Runspaces.Runspace]$InRunspace, [Switch]$DoNotAutomaticallyCreate, [Switch]$CreateDataContextHere, [Switch]$ResetDataSource, [System.Management.Automation.ScriptBlock[]] ${On_PropertyChanged}, [System.Management.Automation.ScriptBlock[]] ${On_OutputChanged}, [System.Management.Automation.ScriptBlock[]] ${On_ErrorChanged}, [System.Management.Automation.ScriptBlock[]] ${On_WarningChanged}, [System.Management.Automation.ScriptBlock[]] ${On_DebugChanged}, [System.Management.Automation.ScriptBlock[]] ${On_VerboseChanged}, [System.Management.Automation.ScriptBlock[]] ${On_ProgressChanged}, [System.Management.Automation.ScriptBlock[]] ${On_IsRunningChanged}, [System.Management.Automation.ScriptBlock[]] ${On_IsFinishedChanged}, [System.Management.Automation.ScriptBlock[]] ${On_TimeStampedOutputChanged} ) process { if (-not $control ) { return } $parent = Get-ParentControl -Control $control if (-not $parent) { $createDataContextHere = $true} if ($createDataContextHere) { $target = $control } else { $target = $parent } if ($ResetDataSource -or $target.DataContext -isnot [ShowUI.PowerShellDataSource]) { if ($target.DataContext) { Write-Debug "Overwriting existing data context" } $target.DataContext = Get-PowerShellDataSource -Parent $target -Script { } if ($target.CommandBindings.Add) { if (-not $target.CommandsBindings.Count) { $cmdBind = New-Object Windows.Input.CommandBinding @( [ShowUI.ShowUICommands]::BackgroundPowerShellCommand,{ . Initialize-EventHandler $sb = try { [ScriptBlock]::Create($_.Parameter) } catch { } Invoke-Background -ScriptBlock $sb trap { . Write-WPFError continue } }, { $sb = try { [ScriptBlock]::Create($_.Parameter) } catch { } . Initialize-EventHandler $_.CanExecute = -not (Get-PowerShellOutput -GetDataSource | Select-Object -ExpandProperty IsRunning) trap { . Write-WPFError continue } } ) $target.CommandBindings.Add($cmdBind) } } } $eventParameters = @{} foreach ($eventName in ($psBoundParameters.Keys -like "On_*")) { $eventParameters.$eventName = $psBoundParameters[$eventName] } $handlerNames = @($target.DataContext.Resources.EventHandlers.Keys) if ($handlerNames) { foreach ($handler in $handlerNames) { $handlerMethod = "remove_$($handler.Substring(3))" $target.DataContext.$handlerMethod.Invoke($target.DataContext.Resources.EventHandlers[$handler]) $null = $target.DataContext.Resources.EventHandlers.Remove($handler) } } Set-Property -inputObject $target.DataContext -property $eventParameters $target.DataContext.Parent = $target $target.DataContext.Command.Commands.Clear() if ($InRunspace) { $target.DataContext.Command.Runspace = $InRunspace } if ($target.DataContext.Command.Runspace.RunspaceAvailability -ne 'Available') { Write-Error "Runspace was busy. Will not run $command" return } if ($parameter) { $target.DataContext.Command.Runspace.SessionStateProxy.PSVariable.Set('CommandParameters', $parameter) if ($debugPreference -ne 'SilentlyContinue') { $parameter } if ($psCmdlet.ParameterSetName -eq 'scriptBlock') { $target.DataContext.Script = ". { $ScriptBlock} @commandParameters" } else { $realCommand = $target.DataContext.Command.Runspace.SessionStateProxy.InvokeCommand.GetCommand($command, "All") $target.DataContext.Script = "$($realCommand.Name) @commandParameters" } $target.DataContext.Resources.Parameter = $parameter } else { if ($psCmdlet.ParameterSetName -eq 'scriptBlock') { $target.DataContext.Script = "$ScriptBlock" } else { $target.DataContext.Script = "$Command" } } } } |