通过父进程控制子进程并接管子进程输入来达到自动输入一些默认命令功能,待默认命令执行完毕后,可以输入命令还原子进程标准输入.
Control.cpp:
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
int main()
{
HANDLE hPipeInputRead = NULL,hPipeOutputWrite = NULL;
HANDLE hPipeInputRead2 = NULL,hPipeOutputWrite2 = NULL;
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;//表示可被子进程所继承
sa.lpSecurityDescriptor = NULL; //安全描述符号一般都设置成NULL,即默认描述符
sa.nLength = sizeof(SECURITY_ATTRIBUTES); //管道长度
BOOL ret = CreatePipe(&hPipeInputRead,&hPipeOutputWrite,&sa,NULL);
if(ret == FALSE){
return -1;
}
ret = CreatePipe(&hPipeInputRead2,&hPipeOutputWrite2,&sa,NULL);
if(ret == FALSE){
return -1;
}
//http://www.360doc.com/content/14/1104/11/11681374_422385772.shtml
//https://zhidao.baidu.com/question/1895877863950674220.html
//http://www.cnblogs.com/luhouxiang/p/3732258.html
//https://support.microsoft.com/zh-cn/help/190351/how-to-spawn-console-processes-with-redirected-standard-handles
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
STARTUPINFOA si = {0};
GetStartupInfoA(&si); //该函数返回进程在启动时被指定的STARTUPINFO 结构
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES ;
si.wShowWindow = SW_SHOWNORMAL;
si.hStdInput = hPipeInputRead; //输入由标准输入 -> 从管道中读取
//si.hStdOutput = hPipeOutputWrite2; //用于本地接管标准输出
si.hStdOutput = hStdOut; //输出由标准输出 -> 输出到管道
PROCESS_INFORMATION pInfo;
memset(&pInfo,0,sizeof(PROCESS_INFORMATION));
ret = CreateProcessA("E:/开发/开发/Message/Debug/Message.exe",
NULL,&sa,NULL,
TRUE,
CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP
,
NULL,NULL,&si,&pInfo);
if(ret == FALSE){
int err = GetLastError();
printf("CreateProcess Error:%d\n",err);
if(err == ERROR_ACCESS_DENIED);
getchar();
return -1;
}else
{
CloseHandle(pInfo.hThread);
CloseHandle(pInfo.hProcess);
}
CloseHandle(hPipeInputRead);
CloseHandle(hPipeInputRead2);
CloseHandle(hPipeOutputWrite2);
CloseHandle(hStdOut);
int index = 0;
char Buffer[1024] = {0};
DWORD writeByte = 0;
DWORD readByte = 0;
while(TRUE)
{
//发送指令
std::string line;
std::getline(std::cin,line);
printf("Control:%s\n",line.c_str());
if(line.compare("close") == 0) break;
line.append("\n");
BOOL ret = WriteFile(hPipeOutputWrite,line.c_str(),line.size() + 1,&writeByte,NULL);
if(ret == FALSE){
break;
}else
{
/*ret = FlushFileBuffers(hPipeOutputWrite);
if(ret == FALSE){
break;
}*/
/*int nRet = PeekNamedPipe(hPipeInputRead2,Buffer,1,(LPDWORD)&readByte,NULL,NULL);
if(nRet){
ReadFile(hPipeInputRead2,Buffer,1024,&readByte,NULL);
printf("%s",Buffer);
}*/
}
}
CloseHandle(hPipeOutputWrite);
return 0;
}
Message.cpp:
#include <stdlib.h>
#include <iostream>
#include <string>
#include <assert.h>
#include <io.h>
#include<stdio.h>
#include <Windows.h>
#include <fcntl.h>
int main()
{
bool activation = false;
/*HANDLE pipe = ::GetStdHandle(STD_INPUT_HANDLE);
int nHandle = _open_osfhandle((long)pipe, _O_TEXT | _O_APPEND);
if (nHandle == -1) return -1;
FILE* pipeFile = _fdopen(nHandle, "rt");*/
std::string line;
while(std::getline(std::cin,line))
{
if(line.size() == 1) continue;
if(strlen(line.c_str()) == 0)
{
line = line.substr(1,line.size());
}
if(strncmp("quit",line.c_str(),4) == 0){
break;
}
//解除PIPE锁定标准输入
else if(strncmp("default",line.c_str(),7) == 0 && !activation)
{
//CONIN$ is the default path of Console Input
//CONOUT$ is the default path of Console Output
//HANDLE hStdIn = CreateFileA(("CONIN$"),GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
//HANDLE hStdOut = CreateFileA(("CONOUT$"),GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
//SetConsoleMode(hStdIn,ENABLE_LINE_INPUT|ENABLE_WINDOW_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_MOUSE_INPUT);
//SetConsoleMode(hStdOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
//SetStdHandle(STD_INPUT_HANDLE,hStdIn);
//assert(hStdIn == ::GetStdHandle(STD_INPUT_HANDLE));
freopen("conin$","r",stdin);
activation = true;
}
else if(strncmp("default",line.c_str(),7) == 0 && activation)
{
//SetStdHandle(STD_INPUT_HANDLE,pipe);
//*stdin = *pipeFile;
//activation = false;
}
else
{
printf("Message:%s\n",line.c_str());
}
line.clear();
}
return 0;
}