创建匿名管道与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;
}