BOOL CmdRuner(char *command, char *pOut)
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead = NULL, hWrite = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
return FALSE;
}
STARTUPINFOA si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFOW);
GetStartupInfoA(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcessA(NULL, (char *)command, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
CloseHandle(hWrite);
CloseHandle(hRead);
return FALSE;
}
CloseHandle(hWrite);
char szBuffer[5 * 1024] = {0};
DWORD dwReaded;
DWORD dwExitCode;
char *pTempOut = pOut;
while (GetExitCodeProcess(pi.hProcess, &dwExitCode))
{
if (dwExitCode != STILL_ACTIVE)
{
break;
}
memset(szBuffer, 0, sizeof(szBuffer));
if (!ReadFile(hRead, szBuffer, sizeof(szBuffer) - 1, &dwReaded, NULL))
{
break;
}
memcpy(pTempOut, szBuffer, dwReaded);
pTempOut += dwReaded;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(hRead);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
//---------------使用------------
CString inputStr="dir"; //显示目录
CString strCmd ;
char strOut[10240]={0}; //运行后的结果输出
strCmd .Format( "cmd /c %s ",inputStr);
CmdRuner(strCmd .GetBuffer(),strOut);
=====方案2:与管道双向通讯======
//=========CEnginePipe.cpp===============
#include "pch.h"
#include "CEnginePipe.h"
#include <afxmt.h>
#define PIPE_BUFSIZE (1024 * 5)
static void Trace(CString str)
{
OutputDebugString(str);
OutputDebugString("\n");
}
static UINT WINAPI EnginePipeProcThread(LPVOID lpParam)
{
CEnginePipe *pipe = (CEnginePipe *)lpParam;
HANDLE hInputWrite, hInputRead;
HANDLE hOutputWrite, hOutputRead;
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi;
STARTUPINFO si;
// 设置安全属性
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// 创建用于输出的管道
if (!CreatePipe(&hOutputRead, &hOutputWrite, &sa, 0))
{
Trace("CreatePipe failed! output read err.");
return 1;
}
// 创建用于输入的管道
if (!CreatePipe(&hInputRead, &hInputWrite, &sa, 0))
{
Trace("CreatePipe failed! input read err.");
return 2;
}
// 确保读取句柄不被继承
SetHandleInformation(hOutputRead, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(hInputWrite, HANDLE_FLAG_INHERIT, 0);
// 设置启动信息
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.hStdError = hOutputWrite;
si.hStdOutput = hOutputWrite;
si.hStdInput = hInputRead;
si.dwFlags = STARTF_USESTDHANDLES |STARTF_USESHOWWINDOW;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
// 创建子进程(这里后台加载exe)
if (!CreateProcess(NULL, pipe->m_strPipeName.GetBuffer(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
Trace("CreatePipe failed! create process err.");
return 3;
}
// 关闭不需要的句柄
CloseHandle(hOutputWrite);
CloseHandle(hInputRead);
pipe->m_hInputWrite = hInputWrite;
// 读取和写入循环
DWORD dwRead, dwWritten;
CHAR chBuf[PIPE_BUFSIZE];
BOOL bSuccess = FALSE;
DWORD bytesAvail = 0;
while (TRUE)
{
// 检查管道中是否有数据
PeekNamedPipe(hOutputRead, NULL, 0, NULL, &bytesAvail, NULL);
if (bytesAvail > 0)
{
bSuccess = ReadFile(hOutputRead, chBuf, PIPE_BUFSIZE - 1, &dwRead, NULL);
if (bSuccess && dwRead > 0)
{
chBuf[dwRead] = '\0';
Trace("=======================================");
Trace(chBuf);
::SendMessageA(pipe->m_hWnd, WM_ENGINEPIPE_MSG, dwRead, (LPARAM)chBuf);
}
}
else
Sleep(50);
// 检查进程是否还在运行
DWORD exitCode;
GetExitCodeProcess(pi.hProcess, &exitCode);
if (exitCode != STILL_ACTIVE)
{
break;
}
}
// 清理
CloseHandle(hOutputRead);
CloseHandle(hInputWrite);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
pipe->m_hInputWrite = NULL;
Trace("Subprocess exited with code!\n");
return 0;
}
CEnginePipe::CEnginePipe()
{
}
CEnginePipe::~CEnginePipe()
{
}
int CEnginePipe::SendCmd(CString cmdStr)
{
DWORD dwWritten = 0;
CString command = cmdStr + "\n";
WriteFile(m_hInputWrite, command, strlen(command), &dwWritten, NULL);
return (int)dwWritten;
}
int CEnginePipe::CreateEnginePipe(HWND hWnd,CString strPipeName)
{
m_hWnd = hWnd;
m_strPipeName = strPipeName;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)EnginePipeProcThread,
this, 0, NULL);
return 0;
}
//===============CEnginePipe.h===================
#pragma once
#define WM_ENGINEPIPE_MSG (WM_USER + 0x1000)
class CEnginePipe
{
public:
CEnginePipe();
~CEnginePipe();
HANDLE m_hInputWrite;
CString m_strPipeName;
HWND m_hWnd;
public:
int CreateEnginePipe(HWND hWnd,CString strPipeName);
int CEnginePipe::SendCmd(CString cmdStr);
};
该代码段展示了如何使用Windows API函数CreateProcessA来执行命令(如`dir`),并通过管道读取其输出结果。首先创建管道,然后设置STARTUPINFO结构以重定向进程的标准输出和错误到管道,接着调用CreateProcessA启动命令,读取管道中的数据,并等待进程结束。

被折叠的 条评论
为什么被折叠?



