创建匿名管道与CMD程序进行交互

注意事项:

1.匿名管道读取缓冲区大小为4096字节。

2.发送消息后我延迟了500毫秒等待cmd返回数据,这个可以根据实际情况进行修改。

#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#define BUFF_SIZE 4096

int main(int argc, char* argv[])
{
    HANDLE hReadPipe, hWritePipe, hReadPipe2, hWritePipe2, hi, ho;
    char Buff[BUFF_SIZE];    // Buffer
    SECURITY_ATTRIBUTES sa;  // Security attributes
    STARTUPINFOA si = { sizeof(si) };  // Startup information, initialize the length
    PROCESS_INFORMATION pi;  // Process information
    DWORD BytesRead, BytesWrite;

    sa.nLength = sizeof(sa);    // Initialize security attributes
    sa.lpSecurityDescriptor = 0;
    sa.bInheritHandle = TRUE;    // Allow child processes to inherit handles from the parent process
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;    // Flags to determine valid members
    si.wShowWindow = SW_HIDE;    // Hide the window for the child process

    /* Create pipes */
    if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0))     // Child process writes, parent process reads
    {
        printf("Failed to create pipe\n");
        exit(1);
    }
    if (!CreatePipe(&hReadPipe2, &hWritePipe2, &sa, 0))    // Child process reads, parent process writes
    {
        printf("Failed to create pipe\n");
        exit(1);
    }
    printf("Pipe created successfully\n");

    /* Create child process */
    hi = GetStdHandle(STD_INPUT_HANDLE);
    ho = GetStdHandle(STD_OUTPUT_HANDLE);    // Record the original standard input and output handles of the parent process for restoration
    SetStdHandle(STD_INPUT_HANDLE, hReadPipe2);
    SetStdHandle(STD_OUTPUT_HANDLE, hWritePipe);    // Redirect standard input and output handles to pipe handles for child process inheritance
    GetStartupInfo(&si);    // Get current process information
    char s[] = "C:\\Windows\\System32\\cmd.exe";
    int sta = CreateProcess(s, NULL, NULL, NULL, TRUE, FALSE, NULL, NULL, &si, &pi);    // Create child process, the fifth parameter should be TRUE to allow handle inheritance
    SetStdHandle(STD_INPUT_HANDLE, hi);
    SetStdHandle(STD_OUTPUT_HANDLE, ho);    // Restore the standard input and output handles of the parent process
    if (!sta)
    {
        printf("Child process creation failed\n");
        exit(1);
    }
    else
    {
        printf("PROCESS ID: %d\n", pi.dwProcessId);
    }

    WaitForInputIdle(pi.hProcess, INFINITE);    // Wait for the child process to finish starting
    Sleep(100);    // Wait for the child process to finish starting

    while (1)  
    {
        PeekNamedPipe(hReadPipe, Buff, BUFF_SIZE-1, &BytesRead, 0, 0);    // Peek the pipe content to prevent blocking the process with ReadFile
        if (BytesRead)    // If the pipe is not empty
        {
            memset(Buff, 0, sizeof(Buff));
            ReadFile(hReadPipe, Buff, BUFF_SIZE-1, &BytesRead, 0);    // Read the echo information
            printf("%s", Buff);
        }
        else
        {
            break;
        }
    }

    /* Send messages */
    std::string command;

    while (1)
    {
        std::getline(std::cin, command);

        if (command == "exit") {
            TerminateProcess(pi.hProcess, 0);
            break;
        }
        command += "\n";

        if (WriteFile(hWritePipe2, command.c_str(), command.size(), &BytesWrite, 0))    // Send message to the child process
        {
        }
        else exit(1);
        Sleep(500);
        while (1)  
        {
            PeekNamedPipe(hReadPipe, Buff, BUFF_SIZE-1, &BytesRead, 0, 0);    // Peek the pipe content to prevent blocking the process with ReadFile
            if (BytesRead)    // If the pipe is not empty
            {
                memset(Buff, 0, sizeof(Buff));
                ReadFile(hReadPipe, Buff, BUFF_SIZE-1, &BytesRead, 0);    // Read the echo information
                printf("%s", Buff);
                Sleep(20);  
            }
            else
            {
                break;
            }
        }
    }

    CloseHandle(hi);
    CloseHandle(ho);
    CloseHandle(hReadPipe);
    CloseHandle(hReadPipe2);
    CloseHandle(hWritePipe);
    CloseHandle(hWritePipe2);    // Close handles
    return 0;
}