#include "stdafx.h"
#include "cmd.h"
#include <string>
#include <iostream>
cmd::cmd() {
// 初始化 m_pi
InitializeCriticalSection(&m_cs);
ZeroMemory(&m_pi, sizeof(m_pi));
}
cmd::~cmd() {
DeleteCriticalSection(&m_cs);
close();
}
CString SendCmd(CString strCommand) {
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE hReadPipe, hWritePipe;
CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE; // 隐藏控制台窗口
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
// 获取当前程序路径并切换到scrcpy64子目录
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH);
CString sCurrentDir = szPath;
sCurrentDir = sCurrentDir.Left(sCurrentDir.ReverseFind('\\')) + _T("\\scrcpy64");
CString sCmdLine;
sCmdLine.Format(_T("cmd.exe /c \"%s\""), strCommand);
if (CreateProcess(
NULL,
sCmdLine.GetBuffer(),
NULL,
NULL,
TRUE,
CREATE_NO_WINDOW,
NULL,
sCurrentDir,
&si,
&pi)
) {
CloseHandle(hWritePipe); // 必须关闭写入端
// 读取命令输出
CHAR buffer[4096];
DWORD bytesRead;
CString sResult;
while (ReadFile(hReadPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead) {
buffer[bytesRead] = 0;
sResult += CString(buffer);
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hReadPipe);
return sResult;
}
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
return _T("Error: CreateProcess failed");
}
BOOL cmd::创建cmd() {
SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
// 创建输入管道(父写子读)
HANDLE hChildStdinRead;
if (!CreatePipe(&hChildStdinRead, &m_hChildStdinWrite, &sa, 0)) {
AfxMessageBox(_T("创建输入管道失败"));
return FALSE;
}
// 创建输出管道(子写父读)
HANDLE hChildStdoutWrite;
if (!CreatePipe(&m_hChildStdoutRead, &hChildStdoutWrite, &sa, 0)) {
AfxMessageBox(_T("创建输出管道失败"));
CloseHandle(hChildStdinRead);
CloseHandle(m_hChildStdinWrite);
return FALSE;
}
// 获取工作目录(scrcpy64子目录)
TCHAR szWorkDir[MAX_PATH];
GetModuleFileName(NULL, szWorkDir, MAX_PATH);
TCHAR* pLastBackslash = _tcsrchr(szWorkDir, _T('\\'));
if (pLastBackslash) *pLastBackslash = _T('\0');
_stprintf_s(szWorkDir, MAX_PATH, _T("%s\\scrcpy64"), szWorkDir);
// 配置进程启动信息
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hChildStdinRead;
si.hStdOutput = hChildStdoutWrite;
si.hStdError = hChildStdoutWrite;
// 创建CMD进程
TCHAR cmdLine[] = _T("cmd.exe");
if (!CreateProcess(
NULL, cmdLine, NULL, NULL, TRUE, 0,
NULL, szWorkDir, &si, &m_pi
)) {
AfxMessageBox(_T("创建进程失败"));
CloseHandle(hChildStdinRead);
CloseHandle(m_hChildStdinWrite);
CloseHandle(hChildStdoutWrite);
CloseHandle(m_hChildStdoutRead);
m_hChildStdinWrite = NULL;
m_hChildStdoutRead = NULL;
return FALSE;
}
// 关闭子进程端不需要的句柄
CloseHandle(hChildStdinRead);
CloseHandle(hChildStdoutWrite);
m_hChildProcess = m_pi.hProcess;
return TRUE;
}
void cmd::sendStr(const CString& str) {
if (!m_hChildStdinWrite || !m_hChildStdoutRead) {
return;
}
EnterCriticalSection(&m_cs);
// 发送命令(附加换行符)
CStringA cmd = CStringA(str) + "\r\n";
DWORD dwWritten;
if (!WriteFile(m_hChildStdinWrite, cmd, cmd.GetLength(), &dwWritten, NULL)) {
LeaveCriticalSection(&m_cs);
return;
}
// 等待命令执行完成(检测提示符)
const std::string prompt = ">"; // CMD提示符特征
m_outputBuffer.clear();
char buffer[4096];
DWORD dwRead;
while (true) {
if (!ReadFile(m_hChildStdoutRead, buffer, sizeof(buffer) - 1, &dwRead, NULL) || dwRead == 0)
break; // 读取失败或管道关闭
buffer[dwRead] = '\0';
m_outputBuffer += buffer;
// 检查是否出现命令提示符(表示上一条命令结束)
if (m_outputBuffer.find(prompt) != std::string::npos) {
break;
}
}
LeaveCriticalSection(&m_cs);
}
void cmd::close() {
// 关闭标准输入管道(写端)
if (m_hChildStdinWrite != NULL) {
CloseHandle(m_hChildStdinWrite);
m_hChildStdinWrite = NULL;
}
// 关闭标准输出管道(读端)
if (m_hChildStdoutRead != NULL) {
CloseHandle(m_hChildStdoutRead);
m_hChildStdoutRead = NULL;
}
// 终止子进程
//if (m_hChildProcess != NULL) {
// // 尝试等待进程正常退出(500ms超时)
// if (WaitForSingleObject(m_hChildProcess, 500) == WAIT_TIMEOUT) {
// TerminateProcess(m_hChildProcess, 0); // 强制终止
// }
// CloseHandle(m_hChildProcess);
// m_hChildProcess = NULL;
//}
if (m_hChildProcess != NULL) {
TerminateProcess(m_hChildProcess, 0); // 强制终止
CloseHandle(m_hChildProcess);
m_hChildProcess = NULL;
}
}
#pragma once
#include <Windows.h>
#include <atlconv.h>
#include <tchar.h>
#include <string>
class cmd {
public:
cmd();
~cmd();
BOOL 创建cmd();
void sendStr(const CString& str);
void close();
public:
void 点击(CString dev, int x, int y);
private:
HANDLE m_hChildStdinWrite = NULL; // 管道写入句柄(输入)
HANDLE m_hChildStdoutRead = NULL; // 管道读取句柄(输出)
HANDLE m_hChildProcess = NULL; // 子进程句柄
PROCESS_INFORMATION m_pi; // 修改:移除初始化
std::string m_outputBuffer; // 存储输出内容
CRITICAL_SECTION m_cs;
};
CString SendCmd(CString strCommand); ------------------void cmd::sendStr(const CString& str) 改成CStrig cmd::sendStr(const CString& str) ;发送命令执行完成后返回控制台输出的内容
最新发布