Videos
Links
MS Learn Tutorial: Set the progress bar in the Windows Terminal
Summary
So this is basically what I want to showcase here:
As you can see, progress there is not only displayed using the default posh progress visualization in the shell itself but also on the UI components of the Windows Terminal (tab-icon and task-bar icon). I like this because especially the task-bar progress enables you to see progress on terminal windows in the background.
In this article I’ll concentrate on PowerShell and .NET but you can use other shells as well because it is based on encoded sequences sent to the output stream.
Solution
So all you need to do is this. If you want to display a progress this way you need to write a OSC-sequence to the shell like this:
$percentage = 50
Write-Host -NoNewline ([char]27 + "]9;4;1;$percentage" + [char]7)
The magic truck here is the ;1;
part (before the percentage) in that string. This represents the state of the progress which can be one of 5 values:
state | Meaning |
---|---|
0 | (default) Progress invisible |
1 | Set progress in default mode. |
2 | Set progress in error mode. |
3 | Indeterminate state |
4 | Set progress in warning mode. |
So lets try them out.
Sample code
The ongoing progress shown in the video at the top was achieved with this script:
function Show-Progress() {
[CmdletBinding()]
[OutputType('hashtable')]
param (
$Percentage = 0,
$State = 1
)
Write-Host -NoNewline ([char]27 + "]9;4;$State;$Percentage" + [char]7)
}
function Hide-Progress() {
Show-Progress -State 0
}
For ($i=0; $i -le 100; $i++) {
Start-Sleep -Milliseconds 1
Show-Progress -Percentage $i
Write-Progress -Id 1 -Activity "First Write Progress" -Status "Current Count: $i" -PercentComplete $i -CurrentOperation "Counting ..."
}
Hide-Progress
So simply speaking we have 2 methods Show-Progress
and Hide-Progress
which we simply call to write the OSC sequence. Thats it. This display default progress.
So with that we can try out different stuff. Lets to the indeterminate progress state for 3 seconds:
Show-Progress -State 3
Start-Sleep -Seconds 3
This gives you:
This leaves us just with the severity level states.
Warning is achieved with
Show-Progress -Percentage 20 -State 4
which looks like this:
So this only changes the color of the progress in the taskbar.
Setting this now to 2 (error) will simple show it as red:
Using it in .NET
So as you saw this is just outputting stuff to the shell. Thats also possible in .NET. So
enum TerminalProgress
{
Disabled = 0,
Default = 1,
Error = 2,
Indetermined = 3,
Warning = 4
}
static void SetProgress(int percentage = 0, TerminalProgress state = TerminalProgress.Default)
{
Console.Write($"\x1b]9;4;{(int)state};{percentage}\x07");
}
static void HideProgress()
{
SetProgress(0, TerminalProgress.Disabled);
}
static void Main(string[] args)
{
SetProgress(20);
Console.ReadKey();
SetProgress(0, TerminalProgress.Indetermined);
Console.ReadKey();
SetProgress(60, TerminalProgress.Error);
Console.ReadKey();
SetProgress(20, TerminalProgress.Warning);
Console.ReadKey();
HideProgress();
}
Conclusion
This is a nice extension to console UIs. So far I could not reproduce this on any of my Mac terminals (iTerm2, Terminal, Warp). So I guess it is only working on Windows Terminal for me so far. Especially the progress bar on the taskbar is obviously very specific to Windows as well.