Why don't cmdlets use the console API?

According to MSDN for highly encouraged development guidelines :

Cmdlets should not use the API Console .

Why is this?

If I write [Console]::Write("test") , it works as well as

 Write-Host "test" 

EDIT: It is well known that Write-Host should be avoided. When MSDN claims to not use the Console API, can they be assumed to imply that we should not use Write-Host , since it uses the console API behind the scenes?

+5
source share
2 answers

The main reason you shouldn't use console related features is that not all PowerShell host environments are consoles.

While a typical use case is to run PowerShell in the console, PowerShell does not need a console and can interact with various types of host systems.

So that your code remains portable, it should not assume a console.

However, it can be assumed that there is a host (called an abstraction) that PowerShell provides using the $HOST automatic variable.
However, the host capabilities are different , which historically created problems, even if the console API was not used directly, but its abstraction is PowerShell, Write-Host - see below.


PowerShell provides a hosting API ,

by which PowerShell runtime can be integrated into other applications . These applications can then use PowerShell functionality to implement certain operations, including through a graphical interface.

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

The regular PowerShell console using the Window Window console ( conhost.exe ) on Windows, therefore, only one PowerShell node implementation - PowerShell ISE - is another example, as is the Microsoft Exchange Server (2007 +) GUI.


Regarding Write-Host :

Prior to PSv4 , as the name implies, it is used to write to a host β€” which may or may not be a console β€” so Write-Host may not actually work on hosts that do not support user interaction ; see this question .

Starting with PSv5, Write-Host safe to use because it is now written to a new host-independent information stream (number 6 ) - see Get-Help about_Redirection and the next section.

Note that Write-Host still executes and always generates output outside the normal PowerShell output stream β€” its output should be a β€œcomment” (user feedback), not data.

Although Write-Host is safe for use in PSv5 +, it exists for backward compatibility, so instead consider using Write-Information -InformationAction Continue or using Write-Information with the preference variable $InformationPreference set to Continue because:

  • "Write-Host" is now a bit wrong, given that it does not actually write directly to the host.

  • Write-Host , in the interests of backward compatibility, does not integrate with the $InformationPreference preference variable - see below.

  • Write-Host still offers console-supported formatting options ( -ForegroundColor , -BackgroundColor ), which not all support (ultimately).


Write-Host vs Write-Information :

PetSerAl tip caps for his help in the following.

Write-Information introduced in PSv5 is a cmdlet that integrates fully with the new host-independent information stream (number 6 ).
It is noteworthy that you can redirect and thus draw Write-Information / Write-Host output with 6> , which was not possible with Write-Host in PSv4.

Also note that this redirection works even with the default $InformationPreference , SilentlyContinue , which controls only the display and not the output aspect (only using the -InformationAction Ignore general parameter really suppresses recording to the stream).

According to how PowerShell handles errors and warnings, the Write-Information display behavior is controlled by the new preference variable $InformationPreference / the new general cmdlet -InformationAction parameter.
Write-Information default behavior should be quiet - $InformationPreference defaults to SilentlyContinue .

Note that Write-Information has no direct formatting options [1] and instead offers tagging with the -Tags [2] option.

In contrast, for backward compatibility, Write-Host effectively behaves like a Write-Information -InformationAction Continue , i.e. it displays by default, and the only way to disable it is to use Write-Host -InformationAction Ignore [3] - it does not take into account the value of the $InformationPreference SilentlyContinue (however, it observes other values, such as Inquire ).


[1] PetSerAl indicates that you can transfer formatting information to Write-Information , but only in obscure form, which is not even documented in terms of PSv5.1; eg.:
Write-Information -MessageData ([System.Management.Automation.HostInformationMessage] @{Message='Message'; ForegroundColor='Red'}) -InformationAction Continue

[2] Note that the name of the Tags parameter actually violates one of the highly recommended cmdlet development rules : it must be a Tag (singular).

[3] PetSerAl explains that this behavior stems from Write-Host passing the PSHOST tag to Cmdlet.WriteInformation behind the scene.

+7
source

[Console]::Write or Write-Host is basically the same . They both write a message to the console, which can be seen on the screen.

The main reason this is discouraged is because it interrupts the workflow. The output of the Write-Host cmdlet cannot be transferred or used later. Now, if the script runs on a machine without graphical output or similar restrictions, the command is lost.

In accordance with this and this , you should use Write-Output , which sends a message to the pipeline where it can be used additionally. In addition, you can use exceptions if your message is for reporting an error.

+2
source

Source: https://habr.com/ru/post/1258188/


All Articles