当我使用CreateProcess()创建一个进程时,我可以从它的stdOut中读取而没有任何问题。为此,我创建了管道并通过STARTUPINFO将它们传递给流程。后来我可以使用ReadFile从stdOut中读取。
当尝试使用CreateProcessWithLogonW执行相同的操作(该进程以不同的用户身份启动)时,它不起作用。这里ReadFile返回FALSE。
所以我的问题是:甚至可以阅读stdOut吗?如果是这样,那么必须对“普通”CreateProcess案例做些什么?
谢谢!
BTW: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
答案 0 :(得分:0)
CreateProcessWithLogonW正确启动新进程吗?
查看MSDN我看到CreateProcess和CreateProcessAsUser可以继承所有句柄。我没有在CreateProcessWithLogonW或CreateProcessWithTokenW上看到这样的评论。所以我的猜测是它可能不会按你的方式工作。
但你仍然可以尝试