1

I want to launch a Python console with CreateProcessW, and then to send some commands to its stdin, using the method discribed here. The process seems to be correctly launched, but commands have no effect.

I tried the same code, replacing "python.exe" with other executables and they work just fine: they receive and react to commands sent.

Also, I can make the process to open in a new console (using si.dwFlags), but no input/output is displayed, so it is difficult to have any feedback. For now, I have tried for example sending "exit()", which should close the process, or other code which should produce side effects.

So:

  • Does someone know the reason this approach doesn't work with python.exe?
  • Is it possible to make the application launched display its input/output in the console?

I know there are other options to do this, like embedding the python interpreter in C and use PyRun_SimpleString (https://docs.python.org/2/extending/embedding.html) but I would like to know why this approach doesn't work with python.exe.

Thanks in advance.

--

Code to launch the process (for python.exe, a new process is indeed created and the return value from CreateProcessW is OK):

STARTUPINFOW si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES security_attributes;
WCHAR cmd[256] = L"python.exe";

DWORD   _process_id;
HANDLE  _input_read;
HANDLE  _input_write;
HANDLE  _output_read;
HANDLE  _output_write;

security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
security_attributes.bInheritHandle = TRUE;
security_attributes.lpSecurityDescriptor = NULL;

CreatePipe(&_output_read, &_output_write, &security_attributes, 0);
CreatePipe(&_input_read, &_input_write, &security_attributes, 0);

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.hStdInput = _input_read;
si.hStdOutput = _output_write;
si.hStdError = _output_write;
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES | CREATE_NEW_CONSOLE;

ZeroMemory( &pi, sizeof(pi) );

if( CreateProcessW( NULL,       // New command line window. No module name (use command line)
    (LPWSTR)cmd,                // Command line
    NULL,                       // Process handle not inheritable
    NULL,                       // Thread handle not inheritable
    TRUE,                       // Set handle inheritance to FALSE
    CREATE_NEW_CONSOLE,         // No creation flags
    NULL,                       // Use parent's environment block
    NULL,                       // Use parent's starting directory 
    &si,                        // Pointer to STARTUPINFO structure
    &pi))                       // Pointer to PROCESS_INFORMATION structure
{
    _process_id = pi.dwProcessId;
    _open_ok = true;
}

Code to send a command (for other applications, it works fine; for python.exe, WriteFile return value is OK and bytes_written corresponds to the length of the command string, but there is no effect).

DWORD bytes_written;

if(!_open_ok) {
    return FALSE;
}

if( !WriteFile(_input_write, cmd.c_str(), cmd.length(), &bytes_written, NULL)) {
    return false;
}
else if(cmd.length() != bytes_written) {
    return false;
}

return true;
Milo
  • 2,062
  • 16
  • 38
  • http://stackoverflow.com/questions/450865/what-is-the-equivalent-to-posix-popen-in-the-win32-api explains how to use pipes (popen) in w32. This might be useful. – stefaanv Dec 01 '14 at 08:37
  • 1
    It looks like Python is not starting in interactive mode, maybe because it doesn't recognize the console as a tty (see [docs](https://docs.python.org/2/using/cmdline.html)). If you only use ``STARTF_USESHOWWINDOW`` as startup flag, it successfully starts, but then does not work as expected because the stdin/out handles are not shared anymore. Note that ``CREATE_NEW_CONSOLE`` is *not* a startup flag but is valid in the creation parameters argument (just like you did). –  Dec 01 '14 at 10:29
  • Thanks @Tibo, your explanation seems very plausible. Also, I tried the -i flag, as indicated in the docs, but it didn't work. – Milo Dec 02 '14 at 07:52

0 Answers0