Когда я создаю процесс с помощью CreateProcess (), я могу читать его stdOut без каких-либо проблем. Для этого я создаю трубы и передаю их процессу через STARTUPINFO. Позже я могу использовать ReadFile для чтения из stdOut.
При попытке сделать то же самое с CreateProcessWithLogonW (процесс запускается от имени другого пользователя) он не работает. Здесь ReadFile возвращает FALSE.
Итак, мои вопросы: можно ли вообще читать stdOut? Если это так, что нужно сделать иначе, чем в «нормальном» случае CreateProcess?
Спасибо!
Кстати: GetLastError дает мне
* ERROR_BROKEN_PIPE
109 (0x6D)
Труба закончилась. *
после вызова ReadFile.
Редактировать: вот код. Он включает в себя два пути, один с CreateProcess (работает) и один с CreateProcessWithLogonW (не работает).
// Declare handles
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
// Create security attributes
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
bool success = true;
// Create a pipe for the child process's STDOUT
if(!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))
success = false;
// Ensure the read handle to the pipe for STDOUT is not inherited
if(success)
if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
success = false;
if(success)
{
BOOL bSuccess = FALSE;
// Set up members of the PROCESS_INFORMATION structure
PROCESS_INFORMATION piProcInfo;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
if(!isRemote) // WORKS
{
// Declare process info
STARTUPINFO siStartInfo;
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
bSuccess = CreateProcess(NULL,
fullCmdLPSTR, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
}
else // RESULTS IN A BROKEN/ENDED PIPE
{
STARTUPINFOW siStartInfo;
// Set up members of the STARTUPINFOW structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFOW) );
siStartInfo.cb = sizeof(STARTUPINFOW);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
bSuccess = CreateProcessWithLogonW(L"otherUser",
L".",
L"otherPW",
LOGON_WITH_PROFILE,
myExeName,
(LPWSTR)cmdLine.c_str(),
CREATE_UNICODE_ENVIRONMENT,
NULL,
NULL,
&siStartInfo,
&piProcInfo);
}//end if
// If an error occurs...
if(!bSuccess)
{
success = false;
}
else
{
// Close handles to the child process and its primary thread
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}//end if
if(success)
{
// Read output from the child process's pipe for STDOUT
// Stop when there is no more data.
DWORD dwRead;
CHAR chBuf[4096];
bSuccess = FALSE;
// Close the write end of the pipe before reading from the
// read end of the pipe, to control child process execution.
// The pipe is assumed to have enough buffer space to hold the
// data the child process has already written to it.
if(!CloseHandle(g_hChildStd_OUT_Wr))
success = false;
if(success)
{
while(true)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, 4096, &dwRead, NULL);
// When using CreateProcess everything is fine here
// When using CreateProcessWithLogonW bSuccess is FALSE and the pipe seems to be closed
if( ! bSuccess || dwRead == 0 ) break;
chBuf[dwRead] = '\0';
// Write read line
write(chBuf);
}//end while
}//end if
}//end if
}//end if