简体   繁体   中英

WriteConsole doesn't work with PowerShell ISE?

WriteConsole does not work with PowerShell ISE.

Neither WriteConsoleW or WriteConsoleA do.

See, for example, this program:

#include <iostream>
#include <Windows.h>

void w() {
  DWORD written;
  BOOL const success = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"Printed\n", 8, &written, nullptr);
  std::wcout << (success ? L"Success" : L"Failure") << L". Wrote " << written << L" characters." << std::endl;
}

void a() {
  DWORD written;
  BOOL const success = WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "Printed\n", 8, &written, nullptr);
  std::cout << (success ? "Success" : "Failure") << ". Wrote " << written << " characters." << std::endl;
}

int main() {
  w();
  a();
  return 0;
}

Ran from PowerShell (or Command Prompt, or Git Bash), it prints:

Printed
Success (wrote 8 characters)
Printed
Success (wrote 8 characters)

But from PowerShell ISE:

Failure (wrote 0 characters)
Failure (wrote 0 characters)

The reason why is shown by this program:

#include <iostream>
#include <Windows.h>

int main() {
  DWORD const file_type = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
  if (file_type == FILE_TYPE_CHAR) {
    std::cout << "char" << std::endl;
  } else if (file_type == FILE_TYPE_PIPE) {
    std::cout << "pipe" << std::endl;
  } else {
    std::cout << file_type << std::endl;
  }
  return 0;
}

When run from PowerShell (or Command Prompt, or Git Bash), it prints:

char

But from PowerShell ISE:

pipe

WriteConsole cannot write through a pipe, and thus fails. The same thing happens when run from PowerShell / Command Prompt / Git Bash if the output is piped.

To provide background information to Bertie Wheen's helpful answer :

  • Perhaps surprisingly, the Windows PowerShell ISE does not allocate a console by default . (The console-like UI that the ISE presents is not a true Windows console).

  • A console is allocated on demand , the first time a console-subsystem program is run in a session (eg, cmd /c ver )

    • Even once that has happened, however, interactive console-subsystem programs are fundamentally unsupported (try choice /m "Prompt me" , for instance).

Interactively, you can test if a console has been allocated or not with the following command: [Console]::WindowTop ; if there's no console, you'll get a The handle is invalid error.


It follows from the above that your program cannot assume that a console is present when run in the ISE .

One option is to simply not support running in the ISE , given that it is:

As for a successor environment: The actively developed, cross-platform editor that offers the best PowerShell development experience is Visual Studio Code with its PowerShell extension .


As for the potential reason for the poor console support in the ISE : zett42 notes:

A possible reason why ISE developers choose not to allocate a console could stem from the historic difficulties of creating a custom, embedded console within an app's own window. Developers had to resort to hackish, unsupported ways of doing that. Only recently (2018) Windows got a dedicated pseudo-console (ConPTY) API .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM