2011-08-12 22 views
4

CreateProcess()でプロセスを作成すると、stdOutから問題なく読み込むことができます。これを行うには、パイプを作成し、STARTUPINFO経由でプロセスに渡します。後でreadFileを使ってstdOutから読み込むことができます。CreateProcessWithLogonWで作成したプロセスのstdOutから読み取る

CreateProcessWithLogonWで同じことをしようとすると(プロセスは別のユーザーとして起動されます)、動作しません。ここでReadFileはFALSEを返します。

私の質問は次のとおりです:stdOutを読むことさえ可能ですか?そうであれば、 "通常の" CreateProcess-caseとは何を別の方法で行う必要がありますか?

ありがとうございます!

はBTW:。GetLastError関数は、ReadFile関数を呼び出した後、私に

* ERROR_BROKEN_PIPE 109(0x6D) パイプは終了しました*

を与えます。

編集:ここにコードがあります。これには2つのパスが含まれています.1つはCreateProcess(動作)、もう1つは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

CreateProcessの戻り値をチェックしていないようです。私たちにこれを推測させず、コードのスニペットを投稿してください。 –

+0

プロセスは正常に開始します(戻り値はokです)。私はすぐにいくつかのコードを投稿します... – Boris

答えて

0

CreateProcessWithLogonWは、新しいプロセスを正しく開始しますか?

MSDNを見ると、CreateProcessとCreateProcessAsUserはすべてのハンドルを継承できます。私はCreateProcessWithLogonWまたはCreateProcessWithTokenWにそのようなコメントが表示されません。だから私の推測では、あなたのやり方ではうまくいかないかもしれないということです。

しかし、あなたはまだSTARTUPINFOEX :: lpAttributeListに記入するのLogonUserとCreateProcessAsUserまたは

    1. を試してみてください。
  • 関連する問題