In C and C++ command-line programs, is there any differences between running your programs within command prompt or within PowerShell? (e.g.: exception handling, I/O speed, etc.)
Update:
PowerShell (Core) v7.4+ now does support raw byte handling with external programs - see this answer.
The following therefore applies only to Windows PowerShell and PowerShell (Core) 7.3-
The main difference:
cmd.exe
provides true binary (byte-stream) conduits, so that >
, the redirection operator, can capture an external program's raw byte output.
Windows PowerShell and PowerShell (Core) up to v7.3 only ever use text (strings) to communicate with external programs, both on in- and output, which means that external-program output is invariably decoded to .NET strings, which has the following implications:
Even when only using PowerShell's >
operator to send an external program's output to a file, each line output by an external program is first decoded into a .NET string and then, on saving to the target file, encoded again, in this case using the Out-File
cmdlet's default encoding, which the >
operator is an effective alias of.
In Windows PowerShell, that (cmdlet-specific) encoding is UTF-16LE ("Unicode"), whereas in PowerShell (Core) 7, it is BOM-less UTF-8, the encoding used consistently in that PowerShell edition.
Out-File
explicitly and pass it an -Encoding
argument, or, for better performance with input that is already text - as is the case with external-program output - Set-Content
.[1]This decoding-reencoding cycle not only slows things down, but also means:
For text output, the input character encoding (as decoded from the external program) may be different from the output-by-PowerShell character encoding.
Binary in- and output is fundamentally unsupported.
cmd.exe
with cmd /c ...
(on Windows) and to /bin/sh
with sh -c ...
(on Unix-like platforms.See this answer for more information.
[1] Note that -Encoding Utf8
invariably creates UTF-8 files with BOM in Windows PowerShell - see this answer for workarounds in case BOM-less files are needed.