盒子
盒子
文章目录
  1. API
  2. 命令执行
  3. 参数解析

命令行

API

BOOL GetInfoByCmd(CString &strResult, CString strCmd)
{
BOOL bret = FALSE;

HANDLE hOutRead, hOutWrite, hInRead, hInWrite;
hOutRead = hOutWrite = hInRead = hInWrite = NULL;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
//创建管道
if (!CreatePipe(&hOutRead, &hOutWrite, &sa, 0))
goto _end;
if (!CreatePipe(&hInRead, &hInWrite, &sa, 0))
goto _end;
//控制命令行窗口信息
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdInput = hInRead;
si.hStdError = hOutWrite;
si.hStdOutput = hOutWrite;
si.wShowWindow = SW_HIDE; //隐藏命令行窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//进程信息
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));

//创建获取命令行进程
if (strCmd.Find('\n') == -1)
{
// 单行指令
TCHAR szCmd[256] = TEXT("cmd.exe /c"); // 必须单独申请变量,直接CreateProcess会崩溃,BUG??
StrCat(szCmd, strCmd);
if (!CreateProcess(NULL, szCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
goto _end;
}
else
{
// 多行指令 - 最后一条指令必须是exit,否则进程无法退出
// strCmd = TEXT("@echo off\ndir\nexit\n");
TCHAR szCmd[32] = TEXT("cmd.exe");
if (!CreateProcess(NULL, szCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
goto _end;
if (strCmd.Right(1) != TEXT("\n"))
strCmd += TEXT("\n");
if (!WriteFile(hInWrite, CW2A(strCmd).m_psz, strCmd.GetLength(), NULL, NULL))
goto _end;
}
// 等待进程结束
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(hOutWrite); // 关闭Write,避免缓存数据读完后read阻塞
hOutWrite = NULL;
// 缓冲区数据读取
const long MAX_OUT_SIZE = 1024;
char szBuffer[MAX_OUT_SIZE + 1];
memset(szBuffer, 0, sizeof(szBuffer));
DWORD dwRead = 0; // 该参数必须存在,否则某些机器上会崩溃
while (ReadFile(hOutRead, szBuffer, MAX_OUT_SIZE, &dwRead, 0))
{
strResult += CA2W(szBuffer);
memset(szBuffer, 0, sizeof(szBuffer));
}
bret = TRUE;

_end:
//关闭所有的句柄
if (hOutRead)
CloseHandle(hOutRead);
if (hOutWrite)
CloseHandle(hOutWrite);
if (hInRead)
CloseHandle(hInRead);
if (hInWrite)
CloseHandle(hInWrite);
if (pi.hProcess)
CloseHandle(pi.hProcess);
if (pi.hThread)
CloseHandle(pi.hThread);
return bret;
}

命令执行

// 常规指令
UINT re = WinExec(cmd, SW_HIDE);
if (re <= 31)
{
CString strError;
switch (re)
{
case ERROR_BAD_FORMAT: strError = cmd + TEXT(":ERROR_BAD_FORMAT"); break;
case ERROR_FILE_NOT_FOUND: strError = cmd + TEXT(":ERROR_FILE_NOT_FOUND"); break;
case ERROR_PATH_NOT_FOUND: strError = cmd + TEXT(":ERROR_PATH_NOT_FOUND"); break;
case 0: strError = cmd + TEXT(":系统内存或资源已耗尽"); break;
default: strError = cmd + TEXT(":ERROR"); break;
}
}

// 32位程序启动64位程序
ShellExecute(NULL, NULL, GetRunPath() + TEXT("\\SystemInit64.exe"), NULL, NULL, FALSE);
// 常规指令
ShellExecute(NULL, TEXT("open"), TEXT("net"), TEXT("stop IDReader"), NULL, FALSE);

参数解析

// 下次使用时,封装下返回值
void ParseCmd(LPWSTR lpCmdLine)
{
DWORD len = _tcslen(lpCmdLine);
TCHAR *buf = new TCHAR[len + 1];
ZeroMemory(buf, (len + 1)*sizeof(TCHAR));
memcpy(buf, lpCmdLine, len*sizeof(TCHAR));
TCHAR *tmp = buf;
while (*tmp)
{
TCHAR *b = tmp;
// 先处理tmp指针,避免修改导致定位错误
tmp += _tcslen(tmp);
tmp++;
if (*b == '-')
{
TCHAR *k = b;
TCHAR *v = StrChr(b, '=');
if (v)
{
// 下一个参数分割点,不支持双引号中带空格情况
TCHAR *e = StrChr(v, ' ');
if (e)
*e = '\0';
// 参数解析
*v = '\0';
v++;
}
}
}
delete buf;
}
支持一下
扫一扫,支持一下
  • 微信扫一扫
  • 支付宝扫一扫