c++ 實現遠端CMD

2020-10-07 13:00:37

c++ 實現遠端CMD

#include "stdafx.h"
#include "PipeCmd.h"


void ShowError(char *pszText)
{
	char szErr[MAX_PATH] = {0};
	::wsprintf(szErr, "%s Error[%d]\n", pszText, ::GetLastError());
	::MessageBox(NULL, szErr, "ERROR", MB_OK);
}


// 執行 cmd 命令, 並獲取執行結果資料
BOOL PipeCmd(char *pszCmd, char *pszResultBuffer, DWORD dwResultBufferSize)
{
	HANDLE hReadPipe = NULL;
	HANDLE hWritePipe = NULL;
	SECURITY_ATTRIBUTES securityAttributes = {0};
	BOOL bRet = FALSE;
	STARTUPINFO si = {0};
	PROCESS_INFORMATION pi = {0};

	// 設定管道的安全屬性
	securityAttributes.bInheritHandle = TRUE;
	securityAttributes.nLength = sizeof(securityAttributes);
	securityAttributes.lpSecurityDescriptor = NULL;
	// 建立匿名管道
	bRet = ::CreatePipe(&hReadPipe, &hWritePipe, &securityAttributes, 0);
	if (FALSE == bRet)
	{
		ShowError("CreatePipe");
		return FALSE;
	}
	// 設定新程序引數
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE;
	si.hStdError = hWritePipe;
	si.hStdOutput = hWritePipe;
	// 建立新程序執行命令, 將執行結果寫入匿名管道中
	bRet = ::CreateProcess(NULL, pszCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
	if (FALSE == bRet)
	{
		ShowError("CreateProcess");
	}
	// 等待命令執行結束
	::WaitForSingleObject(pi.hThread, INFINITE);
	::WaitForSingleObject(pi.hProcess, INFINITE);
	// 從匿名管道中讀取結果到輸出緩衝區
	::RtlZeroMemory(pszResultBuffer, dwResultBufferSize);
	::ReadFile(hReadPipe, pszResultBuffer, dwResultBufferSize, NULL, NULL);
	// 關閉控制程式碼, 釋放記憶體
	::CloseHandle(pi.hThread);
	::CloseHandle(pi.hProcess);
	::CloseHandle(hWritePipe);
	::CloseHandle(hReadPipe);

	return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char szCmd[] = "ping www.baidu.com";
	char szResultBuffer[512] = { 0 };
	DWORD dwResultBufferSize = 512;

	// 執行 cmd 命令, 並獲取執行結果資料
	if (FALSE == PipeCmd(szCmd, szResultBuffer, dwResultBufferSize))
	{
		printf("pipe cmd error.\n");
	}
	else
	{
		printf("CMD執行結果為:\n%s\n", szResultBuffer);
	}

	system("pause");
	return 0;
}