Код: Выделить всё
Invoke-Command {
'a'; Write-Verbose 'a' -Verbose
'b'; Write-Verbose 'b' -Verbose
} |
. { process { Write-Verbose "downstream_$_" -Verbose } }
Код: Выделить всё
VERBOSE: downstream_a
VERBOSE: a
VERBOSE: downstream_b
VERBOSE: b
С другой стороны, рассмотрите аналогичную конструкцию, за исключением замены Invoke-Command на собственный скомпилированный командлет:
Код: Выделить всё
Add-Type `
-PassThru `
-TypeDefinition @'
using System.Management.Automation;
namespace n {
[Cmdlet(VerbsLifecycle.Invoke,"SomeScriptBlockThing")]
public class InvokeSomeScriptBlockThing : Cmdlet
{
[Parameter(Mandatory=true,Position=1)]
public ScriptBlock ScriptBlock { get; set; }
protected override void EndProcessing() {
var output = ScriptBlock.Invoke("some_fancy_argument");
foreach (var o in output) {
WriteObject(o);
}
}
}
}
'@ |
% Assembly |
Import-Module
Invoke-SomeScriptBlockThing {
param($SomeFancyArgument)
'a'; Write-Verbose 'a' -Verbose
'b'; Write-Verbose 'b' -Verbose
} |
. { process { Write-Verbose "downstream_$_" -Verbose } }
Код: Выделить всё
VERBOSE: a
VERBOSE: b
VERBOSE: downstream_a
VERBOSE: downstream_b
Настоящая задача, которую я здесь решаю, — получить CancellationToken, используя метод, продемонстрированный здесь. В этом методе вызов командлета должен пережить токен. Естественный способ обеспечить это — сделать так, чтобы командлет сделал токен доступным (где здесь появляется $SomeFancyArgument) для блока сценария, который он вызывает. Но в показанной реализации командлет ничего не выдает до тех пор, пока блок сценария не завершится.
Как я могу сделать так, чтобы порядок выполнения моего командлета соответствовал порядку выполнения моего командлета первый пример? То есть, как я могу заставить свой командлет выводить каждый объект, созданный вызываемым им блоком сценария?
Обратите внимание, что этот старый вопрос и ответ, возможно, является дубликатом, но он появился раньше, чем PowerShell с открытым исходным кодом, и поэтому не имел преимуществ, позволяющих увидеть, как, например, Invoke-Command Cmdlet достигает этой цели. Единственный ответ на этот вопрос позволяет достичь цели путем преобразования блока сценария в строку и запуска совершенно отдельного экземпляра PowerShell, который, среди прочего, вызывает сценарий в совершенно отдельном SessionState без доступа к какой-либо из родительских областей. . Это тот же вопрос, но из другой эпохи.
Подробнее здесь: https://stackoverflow.com/questions/792 ... an-invoked
Мобильная версия