Reading from stdOut of a process created with CreateProcessWithLogonW
When I create a process with CreateProcess() I can read from its stdOut without any problems. To do so I create the pipes and pass them to the process via the STARTUPINFO. Later I can use ReadFile to read from the stdOut.
When trying to do the same thing with CreateProcessWithLogonW (the process is launched as a different user) it does not work. Here ReadFile returns FALSE.
So my questions are: Is it even possible to read the stdOut? If so, what has to be done differently to the "normal" CreateProcess-case?
Thanks!
BTW: GetLastError gives me
*ERROR_BROKEN_PIPE 109 (0x6D) The pipe has been ended.*
after calling ReadFile.
Edit: Here's the code. It includes two paths, one with CreateProcess (works) and one with CreateProcessWithLogonW (does not work).
// 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,
&开发者_StackOverflow中文版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
CreateProcessWithLogonW starts the new process correctly?
Looking at MSDN I see that CreateProcess and CreateProcessAsUser can inherit all handles. I do not see such a comment on CreateProcessWithLogonW or CreateProcessWithTokenW. So my guess is that it might not work your way.
But you still might try
- to LogonUser and CreateProcessAsUser or
- to fill in STARTUPINFOEX::lpAttributeList.
精彩评论