VC++のCreateProcessとCreatePipeでプロセスを実行し、出力を文字列として取得

CreateProcess と CreatePipe を使用して VC++ でプロセスを実行し、出力を文字列として返却するサンプルコードを次に示します。

#include <windows.h>
#include <iostream>
#include <string>
std::string ExecuteCommand(const std::string& cmd)
{
SECURITY_ATTRIBUTES securityAttributes;
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttributes.bInheritHandle = TRUE;
securityAttributes.lpSecurityDescriptor = NULL;
HANDLE StdOutRead, StdOutWrite;
CreatePipe(&StdOutRead, &StdOutWrite, &securityAttributes, 0);
SetHandleInformation(StdOutRead, HANDLE_FLAG_INHERIT, 0);
STARTUPINFOA startupInfo;
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.hStdOutput = StdOutWrite;
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION processInfo;
ZeroMemory(&processInfo, sizeof(processInfo));
if (!CreateProcessA(NULL, const_cast<LPSTR>(cmd.c_str()), NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInfo))
{
std::cerr << "Failed to execute command: " << cmd << std::endl;
return "";
}
CloseHandle(StdOutWrite);
DWORD bytesRead;
const int bufferSize = 4096;
char buffer[bufferSize];
std::string output;
while (ReadFile(StdOutRead, buffer, bufferSize - 1, &bytesRead, NULL))
{
if (bytesRead == 0)
break;
buffer[bytesRead] = '\0';
output += buffer;
}
CloseHandle(StdOutRead);
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
return output;
}
int main()
{
std::string cmd = "dir";
std::string output = ExecuteCommand(cmd);
std::cout << "Command output: " << std::endl;
std::cout << output << std::endl;
return 0;
}

このコードでは、 CreatePipe 関数で匿名パイプを作成して、プロセスの出力をパイプの書き込み先にリダイレクトし、 ReadFile 関数でパイプの読み込み先から出力を取得します。最後に、 CreateProcess 関数でプロセスを開始し、完了するまで待機します。

上記の例では、cmd 変数は実行するコマンドを含んでいます。このコマンドは単純な “dir” コマンドで、現在のディレクトリにあるファイルとフォルダを一覧します。必要に応じて、他のコマンドを実行するように cmd 変数を変更できます。

bannerAds