Хотя запись-вывод не работает внутри метода класса, она работает, если метод возвращает блок сценария, который затем выполняется снаружи, например так:
#Cmdlet you can't edit that outputs whilst running
function foo {
write-output "Beginning complex operation!";
start-sleep 2;
write-output "Important information you would rather not have to wait for!";
start-sleep 2;
write-output "Operation finished!";
}
class IsClass{
static [ScriptBlock]bar(){
#create a ScriptBlock that the must be executed outside
return { foo };
}
}
& $([IsClass]::bar());
<#Output:
Beginning complex operation!
[two second wait]
Important information you would rather not have to wait for!
[two second wait]
Operation finished!
#>
Это относительно хакерское решение. Однако, насколько мне известно, это единственный способ записи вывода командлетов, вызываемых внутри статического метода, когда командлет все еще работает. Использование write-host
внутри командлета, который вызывает метод, недопустимо, если у вас нет доступа к командлетам, которые вы вызываете внутри класса.
Пример без использования блоков скриптов:
#Cmdlet you can't edit that outputs whilst running
function foo {
write-output "Beginning complex operation!";
start-sleep 2;
write-output "Important information you would rather not have to wait for!";
start-sleep 2;
write-output "Operation finished!";
}
#Class that uses the mentioned cmdlet
class IsClass{
static [void]bar(){
#Directly invoke the method
write-host $(foo);
}
}
[IsClass]::bar();
<#Output:
[Awkward 4 second pause]
Beginning complex operation! Important information you would rather not have to wait for! Operation finished!
Также стоит отметить, что второй метод приводит к тому, что весь вывод отображается в одной строке.
Сценарий, в котором вы можете захотеть использовать это, — это если вы пишете сценарий, который будет устанавливать инструменты с помощью командной строки. При установке используются командлеты, которые вы не можете контролировать и выполнение которых занимает несколько минут (например, установка программного обеспечения с помощью Chocolatey). Это означает, что если ход выполнения командлета изменяется (например, при переходе к установке зависимостей программного обеспечения), он не может записать изменение в консоль до завершения полной установки, оставляя пользователя в неведении относительно того, что происходит в данный момент.
ОБНОВЛЕНИЕ: на момент написания этого я также столкнулся со многими проблемами, касающимися использования области внутри блоков сценариев, поскольку они не разделяют область контекста, в котором они были созданы, а только область, в которой они выполняются. Это в значительной степени делает недействительным многое из того, что я здесь упомянул, поскольку означает, что вы не можете ссылаться на свойства класса.
ОБНОВЛЕНИЕ 2: ЕСЛИ вы не используете GetNewClosure!
static [ScriptBlock]bar(){
#create a ScriptBlock that the must be executed outside
$that = $this;
return { $that.ClassVariable }.GetNewClosure();
}
person
Max Hay
schedule
19.11.2019