본문 바로가기

C/Reference

[C] Command Prompt(명령 프롬프트) 창 띄우지 않고 명령어 실행

반응형
#include <iostream>
#include <Windows.h>

namespace EXEC_COMMAND
{
	namespace RETURN
	{
		namespace FAILURE
		{
			const int CREATE_PIPE = 1;
			const int CREATE_PROCESS = 2;
		}
	}
}

int ExecCommand(std::string command, std::string& output);

int main()
{
	std::string output;

	ExecCommand("ping -n 1 142.251.42.164", output);

	std::cout << output << std::endl;
}

int ExecCommand(std::string command, std::string& output)
{
	HANDLE hPipeRead, hPipeWrite;
	SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) };
	saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process.
	saAttr.lpSecurityDescriptor = NULL;

	// Create a pipe to get results from child's stdout.
	if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0))
	{
		return EXEC_COMMAND::RETURN::FAILURE::CREATE_PIPE;
	}

	STARTUPINFOA si = { sizeof(STARTUPINFOA) };
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.hStdOutput = hPipeWrite;
	si.hStdError = hPipeWrite;
	si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing.

	// Requires STARTF_USESHOWWINDOW in dwFlags.
	PROCESS_INFORMATION pi = { 0 };

	BOOL fSuccess = CreateProcessA(NULL, (char*)(command.c_str()), NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

	if (!fSuccess)
	{
		CloseHandle(hPipeWrite);
		CloseHandle(hPipeRead);

		return EXEC_COMMAND::RETURN::FAILURE::CREATE_PROCESS;
	}

	bool bProcessEnded = false;

	for (; !bProcessEnded;)
	{
		// Give some timeslice (50 ms), so we won't waste 100% CPU.
		bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;

		// Even if process exited - we continue reading, if
		// there is some data available over pipe.
		for (;;)
		{
			char buf[1024] = { 0 };
			DWORD dwRead = 0;
			DWORD dwAvail = 0;

			if (!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL))
			{
				break;
			}

			if (!dwAvail) // No data available, return
			{
				break;
			}

			if (!::ReadFile(hPipeRead, buf, min(sizeof(buf) - 1, dwAvail), &dwRead, NULL) || !dwRead)
			{
				// Error, the child process might ended
				break;
			}

			buf[dwRead] = 0;
			output += buf;
		}
	}

	CloseHandle(hPipeWrite);
	CloseHandle(hPipeRead);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	return EXIT_SUCCESS;
}
반응형

'C > Reference' 카테고리의 다른 글

Integrity Level SID 값  (0) 2024.12.23
[C] 연산자 우선순위  (0) 2024.12.20
[C] C언어의 지시어(헤더파일, 전처리, 매크로)  (0) 2024.12.20
[C] 서식 변환 문자열  (0) 2024.12.20
[C] 난수 생성  (0) 2024.12.20