Как для скомпилированного командлета вывести каждый объект сразу из вызванного блока сценария?C#

Место общения программистов C#
Ответить
Anonymous
 Как для скомпилированного командлета вывести каждый объект сразу из вызванного блока сценария?

Сообщение Anonymous »

Примите во внимание следующее

Код: Выделить всё

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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»