-1

I hope your programming is going well.

I have a question that I hope asserts an easy answer due to my lack of knowledge.

I've used this code from this question - CreateProcess cmd.exe read/write pipes deadlock

And everything works well.

The problem is when I run other commands from the cmd.exe shell that require interactivity, for example, python or powershell, I get the initial output then nothing gets written to the pipe.

So this is what my input/output looks like:

static PCSTR commands[] = { "powershell\r\n", "dir\r\n", "help\r\n"};
ULONG n = RTL_NUMBER_OF(commands);
PCSTR* psz = commands;
do 
{
    if (MessageBoxW(0,0, L"force close ?", MB_YESNO) == IDYES)
    {
        DisconnectNamedPipe(hFile);
        break;
    }
    if (p = new U_IRP(&obj))
    {
        PCSTR command = *psz++;
        p->Write(command, (ULONG)strlen(command) * sizeof(CHAR));
        p->Release();
    }
} while (--n)

When the code runs, I get the initial powershell.exe prompt as so

PS C:\Users>

But after that nothing gets written to the pipe.

The code is using CreateProcess(... "cmd.exe" ...) and I have tried changing it from "cmd.exe" to "cmd.exe /c" and "cmd.exe /k", neither of which work.

Perhaps you would know what I need to do read/write output to interpreted such as python or powershell from a CreateProcess() induced pipe? Thanks for your help!

  • 2
    At least show the code of U_IRP and the piece that calls CreateProcess. But better yet, read [ask] and provide a [mcve]. – rustyx Oct 13 '17 at 14:50
  • Questions seeking debugging help must include the specific problem and the shortest code necessary to reproduce it in the question itself. Please read how to create a [MCVE] and [ask]. – tambre Oct 13 '17 at 14:56
  • 1
    C != C++. Tag only with the language that you're using, unless both are actually relevant. – tambre Oct 13 '17 at 14:56
  • Both are actually relevant, and if you click the link I posted the full code is there... – Tim Collins Oct 13 '17 at 15:05
  • The `do {...}` misses the `while`-statement. – alk Oct 13 '17 at 15:09
  • My deepest apologies, but again... the -full code is in the link-... – Tim Collins Oct 13 '17 at 15:10
  • *"in the link"* and *"in the question itself"* aren't quite the same thing. There is a reason why Stack Overflow asks users to produce self-contained questions. – IInspectable Oct 13 '17 at 15:11
  • I'm very sorry for any troubles that posting a stackoverflow direct link that isn't going to die has caused you and the other commenter, but I've included the relevant code at hand and for purposes of ease of reading, and brevity, have excluded 100+ lines of code. – Tim Collins Oct 13 '17 at 15:22
  • Stack Overflow questions can be deleted. While that question may still be visible to users having the [access to moderator tools](https://stackoverflow.com/help/privileges/moderator-tools) privilege, it will no longer be visible to everyone (like yourself). You are also not asked to copy the entire code. To the contrary, a [mcve] should be minimal, i.e. the **shortest** code necessary to illustrate the issue. – IInspectable Oct 13 '17 at 15:46
  • The way this question is going it'll never get an answer anyways so I doubt it even matters. – Tim Collins Oct 13 '17 at 15:56
  • Could be a direct result of the fact, that the question isn't going anywhere. People have tried to point out, what's wrong with it, but you refuse to take that in. You have been given useful links, and still don't feel like putting any work into writing a good question. – IInspectable Oct 13 '17 at 16:11
  • *I get the initial powershell.exe prompt as so.. But after that nothing gets written to the pipe.* - i run this code and got full output from powershell - https://pastebin.com/Ja6RSxNx – RbMm Oct 13 '17 at 16:12
  • i think you have error with log (relative big data from dir command). all worked correct (data sended to pipe) - if use next `{ "powershell\r\n", "dir\r\n", "help\r\n", "exit\r\n", "exit\r\n" };` - powershell and cmd finally exited as well - https://pastebin.com/sHFVHqk1 – RbMm Oct 13 '17 at 16:19
  • RbMm - thanks for your help. I'm using Win7SP1 build 6.1.7601 and after I issue "powershell\r\n", nothing gets read back. Could you please elaborate on what you mean with "you have error with log" ? – Tim Collins Oct 13 '17 at 16:27
  • Or more specifically, after the first "powershell\r\n", the OnIoComplete() function is no longer called. It's as if the output of powershell is being redirected elsewhere. – Tim Collins Oct 13 '17 at 16:32
  • what i paste - on win10 - now i test on win7 - yes, really got only "powershell Windows PowerShell Copyright (C) 2009 Microsoft Corporation. All rights reserved." and all. need debug for view in what problem – RbMm Oct 13 '17 at 16:36
  • problem not in my program here, but in different ways how cmd interact with powershell. say on windows 7 if you enter in cmd indow command direct - you got output to pipe. need look which handles cmd duplicate to 3-rd program and how interact with it – RbMm Oct 13 '17 at 17:02
  • Yes I think your code is perfectly fine. I've seen this problem before with interactive binaries and often times you need to add some flag to force output to a certain place, for example the /k or /c flag but I tried and it didn't work. My guess is there is some powershell flag that needs to be given on the command line to force output to stdout but I can't find it... – Tim Collins Oct 13 '17 at 17:13

1 Answers1

1

you exec cmd.exe and send command to it via pipe to exec powershell. then all depended from powershell implementation

on window7:

powershell use ReadConsoleW for got input. so it not use you named pipe - not read from it. and you can note that console window become interactive after you exec powershell. so powershell not accept what you write to pipe (it simply not read from it at all) but read user input from screen. however after you manually input some command to console and press enter - you can got pipe output - powershell use (mix) both - WriteFile and WriteConsoleW for output. some information output via WriteFile and some via WriteConsoleW

on windows10:

powershell use ReadFile for got input. and WriteFile for output. so it read you commands from pipe and write results to it. and all perfect worked. also you can note that console window is inactive in this case - you can not enter any text to it (unlike win7)

so with code all absolute ok. problem only in how 3-rd program read and write data. if it not read from your pipe - you nothing can do here

RbMm
  • 31,280
  • 3
  • 35
  • 56
  • Weird, because I know of other programs that can do exactly this. Are you saying it's not possible? – Tim Collins Oct 13 '17 at 21:48
  • @TimCollins - what is not possible ? if program use `ReadConsoleW` instead `ReadFile` - what you can do here ? of course if exist some command line switch to select `ReadConsoleW` vs `ReadFile` but i doubt in this – RbMm Oct 13 '17 at 21:50
  • If an app calls `ReadConsoleW` when attached to a console, try running it with the creation flag `DETACHED_PROCESS` (i.e. don't automatically inherit or allocate a console). – Eryk Sun Oct 13 '17 at 23:12
  • If that fails, and you know this ahead of time, ensure you're attached to the same console and write to the input buffer via `WriteConsoleInput`. If it's also writing to the console screen buffer, in the simple case you can call `CreateConsoleScreenBuffer` and set it to 9999 lines all initialized to NUL, set this as the active screen temporarily, wait on the process, and read the output via `ReadConsoleOutputCharacter`. It's not that simple if you need more than 9999 lines of output, however. – Eryk Sun Oct 13 '17 at 23:12
  • @eryksun - How do I run powershell with DETACHED_PROCESS flag? I'm not calling powershell via CreateProcess(), it's getting called from the command line. Calling CreateProcess(cmd.exe, DETACHED_PROCESS) results in powershell seperating completely from the pipes, no longer gives any output, not even the first lines, and opens in it's own windows which is what I don't want... so if what you say will work please provide context in code. – Tim Collins Oct 13 '17 at 23:24
  • @TimCollins, CMD has no feature to run a process with that flag. If you can't run PowerShell directly, then you have to use the console API. Allocate a hidden console if you're in a GUI process. Then CMD will inherit your hidden console, and you can write to the input buffer and read the screen buffer. But reading from the screen requires active polling if it's more than 9999 lines, since the console will scroll the screen buffer automatically, unlike the way writing to a pipe blocks when it's full. – Eryk Sun Oct 13 '17 at 23:40