通过匿名管道获取CMD运行结果

时间:2023-03-09 15:26:29
通过匿名管道获取CMD运行结果
 #include <iostream>
#include <string>
#include <Windows.h> using namespace std; /*
获取CMD执行结果
cmdLine:要执行的命令
*/
char *GetCmdRet(char *cmdLine); int main(void)
{
char *ret = GetCmdRet("ipconfig");
cout << ret << endl;
free(ret);
cout << "\n====================换个命令玩玩====================\n" << endl;
ret = GetCmdRet("dir");
cout << ret << endl;
free(ret);
system("pause");
return ;
} char *GetCmdRet(char *cmdLine)
{
HANDLE hRead = NULL, hWrite = NULL;
PROCESS_INFORMATION pInfo = { };
SECURITY_ATTRIBUTES se = { };
STARTUPINFO sInfo = { };
char tmpCmd[] = { }, *retStr = NULL;
DWORD dwLen = ;
string ret; se.nLength = sizeof(se);
se.lpSecurityDescriptor = NULL;
se.bInheritHandle = TRUE; // 创建一个匿名管道
CreatePipe(&hRead, &hWrite, &se, ); sInfo.cb = sizeof(sInfo);
sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 这两个常量分别用于设置隐藏窗口+输出目标
sInfo.wShowWindow = SW_HIDE; // 隐藏窗口运行
sInfo.hStdOutput = hWrite; // 让其输出到这个管道去而不是输出到控制台
sInfo.hStdError = hWrite; // 错误信息也是输出到该管道
sprintf_s(tmpCmd, MAX_PATH, "cmd.exe /c %s", cmdLine);
CreateProcess(NULL, tmpCmd, NULL, NULL, TRUE, NULL, NULL, NULL, &sInfo, &pInfo);
CloseHandle(hWrite); while (dwLen != -)
{
// 查看管道中是否有数据
PeekNamedPipe(hRead, NULL, NULL, NULL, &dwLen, NULL);
if (dwLen)
{
memset(tmpCmd, , MAX_PATH);
// 读取管道数据
ReadFile(hRead, tmpCmd, dwLen, &dwLen, NULL);
ret += tmpCmd;
}
else
{
DWORD dwExit = ;
GetExitCodeProcess(pInfo.hProcess, &dwExit);
// 避免程序已经退出,但管道仍有数据的情况
if (dwExit != STILL_ACTIVE)
{
CloseHandle(hRead);
break;
}
}
// 一定要加个延时,否则可能有重复数据
Sleep();
}
retStr = (char *)malloc(sizeof(char)*ret.length() + );
memset(retStr, , ret.length() + );
lstrcpyn(retStr, ret.c_str(), ret.length() + );
return retStr;
}

通过匿名管道获取CMD运行结果