[Windows]_[초급][독립형 하위 프로세스 작성 및 하위 프로세스 읽기 출력]

장면:
1. 일부 외부 도구 명령은 프로그램을 통해 호출해야 한다. 예를 들어 서버를 시작하거나 네트워크 명령을 사용하여 출력을 얻는다.
2. 익명 파이프 CreatePipe를 사용하여 하위 프로세스 출력을 가져옵니다.
참조:
1. MSDN의 주제인'Creating a Child Process with Redirected Input and Output'.
2. Windows Core 프로그래밍 프로세스 섹션
코드:
#include "test_shellrun.h"
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <Windows.h>
using namespace std;

bool ExecuteCommandNoWait(const wchar_t* command)
{
	STARTUPINFOW startupInfo = {sizeof(STARTUPINFOW)};
	GetStartupInfoW(&startupInfo);
	startupInfo.dwFlags=0;
	startupInfo.wShowWindow=SW_HIDE;

	bool ret = true;
	PROCESS_INFORMATION  info;
	wchar_t* wlpcmd = wcsdup(command);
	if (CreateProcessW(NULL , wlpcmd , NULL , NULL , TRUE , CREATE_NO_WINDOW, NULL
		, NULL	, &startupInfo, &info))
	{
		CloseHandle(info.hProcess);
		CloseHandle(info.hThread);
	}else
	{
		 ret = false; 
	}
	free(wlpcmd);
	return ret;
}

std::string ExecuteCommandAndWait(const wchar_t* command,uint32_t wait_millisecond)
{
	SECURITY_ATTRIBUTES sa;
	HANDLE hChildStdoutRd,hChildStdoutWr;

	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;

	std::string buf;
	if (!CreatePipe(&hChildStdoutRd,&hChildStdoutWr,&sa,0))
	{
		return buf;
	}

	if (!SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0))
	{
		CloseHandle(hChildStdoutWr);
		CloseHandle(hChildStdoutRd);
		return buf;
	}

	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );

	ZeroMemory( &si, sizeof(STARTUPINFO) );
	si.cb = sizeof(STARTUPINFO); 
	si.hStdError = hChildStdoutWr;
	si.hStdOutput = hChildStdoutWr;
	si.dwFlags |= STARTF_USESTDHANDLES;

	wchar_t* wlpcmd = wcsdup(command);
	//CREATE_UNICODE_ENVIRONMENT
	if (!CreateProcessW(NULL, wlpcmd,NULL,NULL,TRUE,0 ,NULL,NULL,&si,&pi))
	{    
		CloseHandle(hChildStdoutWr);
		CloseHandle(hChildStdoutRd);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		free(wlpcmd);
		return buf;
	}

	WaitForSingleObject(pi.hProcess,wait_millisecond);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	CloseHandle(hChildStdoutWr);

	char buffer[1024] = {0};
	DWORD bytesRead;

	BOOL ret = false;

	while (true)
	{
		ret = ReadFile(hChildStdoutRd,buffer,1024,&bytesRead,NULL);
		if (!ret || bytesRead == 0)
		{
			break;
		}
		buf.append(buffer,bytesRead);
	}

	CloseHandle(hChildStdoutRd);
	free(wlpcmd);
	return buf;
}
 调用: 
  
  
 
ExecuteCommandNoWait(L"notepad.exe");
std::string output = ExecuteCommandAndWait(L"ping www.baidu.com",-1);
cout << "output: " << output << endl;

주의: ReadFile은 손자 프로세스의 출력을 읽을 때 하위 프로세스가 하위 프로세스를 생성해서 끊깁니다. 이 문제는 잠시 스레드 타이머로 호출됩니다.
CancelIoEx

ReadFile을 닫는 데는 현재 더 좋은 방법이 없습니다. 누가 알고 있는지 메시지를 남겼습니다.

좋은 웹페이지 즐겨찾기