鉴于以下程序,我创建了一个cmd.exe
子进程,为什么我在收到命令输出之前按ENTER
两次(从标准输出管道读取) ?
我的目标是效仿" true" cmd.exe
经验。但是,额外的ENTER
点击有点破坏了这种感觉,因为在收到输出之前会有两个提示(来自子进程)。
另外,我想知道,为什么在子进程cmd.exe
控制台窗口中没有显示提示?它只是空白,但我看到它仍然接收输入,执行它并发回输出。
很乐意解释这个问题。
...谢谢
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define BUFFSZ 1024
int main(int argc, char* argv[])
{
char buf[BUFFSZ];
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
PROCESS_INFORMATION pi;
// Pipe handles
HANDLE hChildStd_IN_Rd, hChildStd_OUT_Wr, hChildStd_OUT_Rd, hChildStd_IN_Wr;
printf("Program started...\n");
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
// Inheritable handles
sa.bInheritHandle = true;
// StdInput pipe
if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &sa, 0))
{
printf("CreatePipe() failed\n");
return -1;
}
// StdOutput pipe
if (!CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &sa, 0))
{
printf("CreatePipe() failed\n");
return -1;
}
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
si.hStdOutput = hChildStd_OUT_Wr;
si.hStdError = hChildStd_OUT_Wr;
si.hStdInput = hChildStd_IN_Rd;
ZeroMemory(&pi, sizeof(pi));
// Create child process
if (!CreateProcess(TEXT("C:\\Windows\\System32\\cmd.exe"), NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
NULL, NULL, &si, &pi))
{
printf("CreateProcess() failed\n");
return -1;
}
unsigned long exit; // Exit code
unsigned long bread; // Bytes read
unsigned long avail; // Bytes available
ZeroMemory(buf, sizeof(buf));
for (;;)
{
// Get termination status of child process
if (!GetExitCodeProcess(pi.hProcess, &exit)) {
printf("GetExitCodeProcess() failed\n");
return -1;
}
if (exit != STILL_ACTIVE) {
break;
}
// Check to see if data available in pipe
PeekNamedPipe(hChildStd_OUT_Rd, buf, BUFFSZ, &bread, &avail, NULL);
if (bread != 0)
{
ZeroMemory(buf, sizeof(buf));
if (avail > BUFFSZ)
{
while (bread >= BUFFSZ)
{
ReadFile(hChildStd_OUT_Rd, buf, BUFFSZ, &bread, NULL);
printf("%s", buf);
ZeroMemory(buf, sizeof(buf));
}
}
else {
// Read all data from StdOut pipe in one chunk
ReadFile(hChildStd_OUT_Rd, buf, BUFFSZ, &bread, NULL);
printf("%s", buf);
}
}
if (_kbhit()) //check for user input.
{
ZeroMemory(buf, sizeof(buf));
*buf = (char)getchar();
WriteFile(hChildStd_IN_Wr, buf, 1, &bread, NULL);
if (*buf == '\r') {
*buf = '\n';
WriteFile(hChildStd_IN_Wr, buf, 1, &bread, NULL);
}
}
}
// Clean up
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hChildStd_IN_Rd);
CloseHandle(hChildStd_OUT_Wr);
CloseHandle(hChildStd_OUT_Rd);
CloseHandle(hChildStd_IN_Wr);
return 0;
}