Search code examples
c++cpowershellcommand-prompt

Difference in running C++ program in command prompt and PowerShell


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.)


Solution

  • 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.

          • To use a different encoding for saving, either use 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.

          • The simplest workaround is to delegate to 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.