为什么cmdlet不使用Console API?

Bac*_*ave 5 powershell

根据强烈鼓励发展指南MSDN:

Cmdlet不应使用Console API.

为什么是这样?

如果我写[Console]::Write("test"),它的效果就像

Write-Host "test"
Run Code Online (Sandbox Code Playgroud)

编辑:众所周知Write-Host应该避免.当MSDN说不使用Console API时,可以安全地假设它们暗示我们不应该使用它们Write-Host,因为它在幕后使用Console API吗?

mkl*_*nt0 9

不应使用与控制台相关的功能的主要原因是并非所有PowerShell主机环境都是控制台.

虽然典型的用例是在控制台中运行PowerShell,但PowerShell 不需要控制台,可以与不同类型的主机环境配合使用.

因此,为了让您的代码保持可移植性,它不应该假设存在控制台.

但是,假设存在(称为抽象)主机,PowerShell通过自动$HOST变量公开,这是安全的.然而,主机
功能各不相同,即使直接使用控制台API ,它也一直存在问题,但它的PowerShell抽象,Write-Host见下文.


PowerShell提供托管API,

所述PowerShell运行时可以嵌入到其它应用程序.然后,这些应用程序可以使用PowerShell功能来实现某些操作,包括通过图形界面公开的操作.

https://en.wikipedia.org/wiki/PowerShell

因此,在Windows上使用控制台窗口主机(conhost.exe)的常规PowerShell控制台只是PowerShell主机的一个实现 - PowerShell ISE是另一个示例,Microsoft Exchange Server管理GUI(2007+)也是如此.


至于Write-Host:

直到PSv4,顾名思义,它曾用于写入主机 - 可能是也可能不是控制台 - 所以Write-Host实际上可能在不支持用户交互的主机上失败 ; 看到这个问题.

从PSv5开始,Write-Host使用是安全的,因为它现在写入新引入的,与主机无关的信息流(数字6) - 请参阅Get-Help about_Redirection下一节.

请注意,Write-Host仍然会在常规PowerShell 输出之外生成并始终生成输出- 其输出应该是"评论"(反馈给用户)而不是数据.

虽然在PSv5 +中使用Write-Host安全的,但它存在向后兼容性,因此请考虑使用
Write-Information -InformationAction Continue或使用Write-Information偏好变量$InformationPreference设置为Continue
,因为:

  • "Write- Host "现在有点用词不当,因为它实际上不再直接写入主机了.

  • Write-Host,为了向后兼容,不与$InformationPreference偏好变量集成- 见下文.

  • Write-Host仍然提供控制台启发的格式化参数(-ForegroundColor,-BackgroundColor),并非所有主机(最终)都支持.


Write-Host对比Write-Information:

PetSerAl的帽子提示他的帮助如下.

Write-Information在PSv5中引入的cmdlet是与新的,独立于主机的信息流(数字6)完全集成的.
值得注意的是,你现在可以重定向,从而捕捉 Write-Information/Write-Host 输出使用6>,这在过去是不可能Write-Host的PSv4-.
另请注意,此重定向甚至可以使用$InformationPreference默认值,SilentlyContinue该默认值仅控制显示,而不是输出方面(仅使用通用参数-InformationAction Ignore真正禁止写入流).

与PowerShell处理错误和警告的方式一致,显示行为Write-Information可通过新的$InformationPreference首选项变量/新的常用-InformationActioncmdlet参数进行控制.
Write-Information默认行为是无声的 - $InformationPreference默认SilentlyContinue.

请注意,Write-Information没有直接格式化参数[1],而是使用参数[2]提供关键字标记 .-Tags

与此相反,为了向后兼容,Write-Host有效的行为像
Write-Information -InformationAction Continue
,即,其由缺省输出,并且只有沉默它的方法是使用Write-Host -InformationAction Ignore[3] -它尊重一个$InformationPreference的值SilentlyContinue(它,然而,尊重其他值,如Inquire).


[1] PetSerAl指出你可以传递格式化信息Write-Information,但只是以一种模糊的方式传递,甚至没有记录为PSv5.1; 例如:
Write-Information -MessageData ([System.Management.Automation.HostInformationMessage] @{Message='Message'; ForegroundColor='Red'}) -InformationAction Continue

[2]请注意参数名称"Tags"实际上违反了一项强烈鼓励的cmdlet开发指南:它应该是"Tag"(单数).

[3] PetSerAl解释说,这种行为源于Write-HostPSHOST标签传递到Cmdlet.WriteInformation幕后.


dav*_*igh 2

[Console]::Write或者说Write-Host基本相同。他们都向控制台写入一条消息,该消息可以在屏幕上看到。

不鼓励这样做的根本原因是它破坏了工作流程。cmdlet的输出Write-Host无法通过管道传送或进一步使用。现在,如果脚本在没有图形输出或类似约束的计算机上运行,​​则命令将丢失。

因此,根据thisthis thread,您应该使用Write-Output,它将输出消息发送到可以进一步使用的管道。此外,如果您的消息旨在表示错误,则可以使用异常。