flexible handling of GetConsoleWidth method's default value would be useful in scripting
Description of the new feature/enhancement
When listing output winget truncates column width(s) to accommodate for the total width of the console, which is determined by a call to GetConsoleWidth in src\AppInstallerCLICore\TableOutput.h
namespace details
{
// Gets the column width of the console.
inline size_t GetConsoleWidth()
{
CONSOLE_SCREEN_BUFFER_INFO consoleInfo{};
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
{
return static_cast<size_t>(consoleInfo.dwSize.X);
}
else
{
return 120;
}
}
}
If the console is not wide enough, output of a column is truncated and a UTF8 Horizontal Ellipsis (…) is append to the end of the column, also in src\AppInstallerCLICore\TableOutput.h; see the first listing in the image below.
void OutputLineToStream(const line_t& line)
{
auto out = m_reporter.Info();
for (size_t i = 0; i < FieldCount; ++i)
{
const auto& col = m_columns[i];
if (col.MaxLength)
{
size_t valueLength = Utility::UTF8ColumnWidth(line[i]);
if (valueLength > col.MaxLength)
{
size_t actualWidth;
out << Utility::UTF8TrimRightToColumnWidth(line[i], col.MaxLength - 1, actualWidth) << "\xE2\x80\xA6"; // UTF8 encoding of ellipsis (…) character
// Some characters take 2 unit space, the trimmed string length might be 1 less than the expected length.
if (actualWidth != col.MaxLength - 1)
{
out << ' ';
}
if (col.SpaceAfter)
{
out << ' ';
}
}
else
{
out << line[i];
if (col.SpaceAfter)
{
out << std::string(col.MaxLength - valueLength + 1, ' ');
}
}
}
}
out << std::endl;
}
When the console is wide enough, all of the columns are output in their entirety; see the second listing in the image below.
However, if you either pipe the output to a subsequent command, such as winget upgrade | Select-Object -skip 3, or you assign it to a variable, GetConsoleWidth uses a hard coded 120 for the console width, because it can't get console buffer info for std out. Besides being truncated, the output is also garbled because it is not captured as UTF8; ; see the third listing in the image below.

Proposed technical implementation details (optional)
Adding native PowerShell support as proposed in #221 would be the ideal solution, however a quick simple patch to bump up the default value to 180+ would be great in the mean time.
namespace details
{
// Gets the column width of the console.
inline size_t GetConsoleWidth()
{
CONSOLE_SCREEN_BUFFER_INFO consoleInfo{};
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
{
return static_cast<size_t>(consoleInfo.dwSize.X);
}
else
{
return 180; // or more if your heart desires 😋
}
}
}
Why truncate at all? If stdout is a file or a pipe, long lines should never be truncated!
Why truncate at all? If stdout is a file or a pipe, long lines should never be truncated!
I agree, but that would require more work, which would become unnecessary once powershell is natively supported, hence the simple solution suggestion to change one default.
Duplicate #2603
[Policy] Area-Output