//コンソールを起動させてコマンドを実行し結果を表示します

#include <stdio.h>
#include <windows.h>


HANDLE initConsole(HANDLE*hPipeW,HANDLE*hPipeR,HANDLE*hPipeE){
	enum {R,W};//R=0 W=1

	//コンソールウィンドウ作成
	FreeConsole();
	AllocConsole();
	
	//標準入出力のハンドルを保存
	HANDLE hOldIn = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE hOldOut = GetStdHandle(STD_OUTPUT_HANDLE);
	HANDLE hOldErr = GetStdHandle(STD_ERROR_HANDLE);

	HANDLE hPipePW[2];
	HANDLE hPipePR[2];
	HANDLE hPipePE[2];

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

	//現在のプロセスの擬似ハンドルを取得します
	HANDLE hProcess = GetCurrentProcess();

	//標準出力の作成
	CreatePipe(&hPipePW[R],&hPipePW[W],&SecAtt,0);//パイプのハンドルを取得
	SetStdHandle(STD_OUTPUT_HANDLE,hPipePW[W]);//標準入出力を入れ替え
	//オブジェクトハンドルの複製
	//複製されたハンドルは、複製元のハンドルと同じオブジェクトを参照します
	DuplicateHandle(hProcess,hPipePW[R],hProcess,&*hPipeR,0,FALSE,DUPLICATE_SAME_ACCESS);
	CloseHandle(hPipePW[R]);
	
	//標準入力の作成
	CreatePipe(&hPipePR[R],&hPipePR[W],&SecAtt,0);//パイプのハンドルを取得
	SetStdHandle(STD_INPUT_HANDLE,hPipePR[R]);//標準入出力を入れ替え
	//オブジェクトハンドルの複製
	//複製されたハンドルは、複製元のハンドルと同じオブジェクトを参照します
	DuplicateHandle(hProcess,hPipePR[W],hProcess,&*hPipeW,0,FALSE,DUPLICATE_SAME_ACCESS);
	CloseHandle(hPipePR[W]);

	//標準エラーの作成
	CreatePipe(&hPipePE[R],&hPipePE[W],&SecAtt,0);//パイプのハンドルを取得
	SetStdHandle(STD_ERROR_HANDLE,hPipePE[W]);//標準入出力を入れ替え
	//オブジェクトハンドルの複製
	//複製されたハンドルは、複製元のハンドルと同じオブジェクトを参照します
	DuplicateHandle(hProcess,hPipePE[R],hProcess,&*hPipeE,0,FALSE,DUPLICATE_SAME_ACCESS);
	CloseHandle(hPipePE[R]);

	//ハンドルを継承したコンソールを起動

	STARTUPINFO si;// スタートアップ情報
	PROCESS_INFORMATION pi;// プロセス情報

	//STARTUPINFO 構造体の内容を取得 
	GetStartupInfo(&si);

	if(CreateProcess(NULL,"cmd",NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)){
		//標準入出力のハンドルを復帰
		SetStdHandle(STD_OUTPUT_HANDLE,hOldOut);
		SetStdHandle(STD_INPUT_HANDLE,hOldIn);
		SetStdHandle(STD_ERROR_HANDLE,hOldErr);
	}else{
		//標準入出力のハンドルを復帰
		SetStdHandle(STD_OUTPUT_HANDLE,hOldOut);
		SetStdHandle(STD_INPUT_HANDLE,hOldIn);
		SetStdHandle(STD_ERROR_HANDLE,hOldErr);
		FreeConsole();
		return 0;
	}

	return pi.hProcess;
}

void closeConsole(HANDLE hProcess){
	//プロセスを強制終了する
	TerminateProcess(hProcess, 0);
	FreeConsole();
}

int main()
{
	HANDLE hPipeW; // 出力
	HANDLE hPipeR; // 入力
	HANDLE hPipeE; // エラー

	HANDLE hProcess;
	hProcess=initConsole(&hPipeW,&hPipeR,&hPipeE);
	if(hProcess){
		//ノンブロッキングモードに設定
		unsigned long mode=PIPE_NOWAIT;
		SetNamedPipeHandleState(hPipeR,&mode,NULL,NULL);
		SetNamedPipeHandleState(hPipeE,&mode,NULL,NULL);

		DWORD dwByte;

		{//コマンドをコンソールに書き込み
			char*commandStr="dir\r\n";
			WriteFile(hPipeW,commandStr,strlen(commandStr),&dwByte,NULL);
			// 書き込みバッファのフラッシュ
			FlushFileBuffers(hPipeW);
		}

		Sleep(1000);//コマンドが処理されるまで待機するウエイト

		{//コンソールから標準出力の読み出し
			// 読み込みバッファのフラッシュ
			FlushFileBuffers(hPipeR);
			char str[1024];
			ReadFile(hPipeR,str,sizeof(str),&dwByte,NULL);
			str[dwByte] = '\0';
			MessageBox(NULL,str,"",NULL);//読み出した内容の表示
		}

		{//コンソールから標準エラーの読み出し
			// 読み込みバッファのフラッシュ
			FlushFileBuffers(hPipeE);
			char str[1024];
			ReadFile(hPipeE,str,sizeof(str),&dwByte,NULL);
			str[dwByte] = '\0';
			MessageBox(NULL,str,"",NULL);//読み出した内容の表示
		}

		closeConsole(hProcess);
	}
	getchar();
	return 0;
}






▲トップページ > Windows と C++