无法在管道 Windows Visual cpp 上写入

发布于 2024-09-07 01:54:51 字数 444 浏览 5 评论 0原文

我创建了两个管道将子进程 stdin 和 stdout 重定向到父进程,如下所示 http://msdn.microsoft.com/en- us/library/ms682499%28VS.85%29.aspx

子进程是一个exe文件。 当使用控制台执行时,它首先在 STDOUT 上返回警告,然后要求来自 STDIN 的是/否输入。 当我从我的 cpp 程序运行子进程时,读取管道成功地从子进程 STDOUT 读取警告行,但是当尝试使用写入管道将“是”或“否”发送到子进程的 STDIN 时,子程序不知何故没有收到它。但是,当我在父进程的 STDIN 上键入它时,子进程会收到 yes 和 no 。

知道为什么会发生这种情况吗?

I created two pipe to redirect child process stdin and stdout to parent process as given in
http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx

The child process is an exe file.
when executed using console it first returns a warning on STDOUT and then asks for a yes/no input from STDIN.
when i am running the child process from my cpp program, the read pipe successfully reads the warning line from childs STDOUT but when try to send "yes" or "no" to child's STDIN using the write pipe the child program somehow does not receive it. however when i type it on the STDIN of parent the child process receives the yes and no .

Any idea why this is happening ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞陪衬 2024-09-14 01:54:51
VOID WriteToPipe(VOID) 
{ 
 DWORD  dwWritten; 
  CHAR chBuf[3];
   sprintf(chBuf,"y\r\n");  
  if(logLevel==1) 
log("trying to write y to child\n",1);
 // Read from a file and write its contents to a pipe. 


    if (! WriteFile(hChildStdinWr, chBuf, 3, 
      &dwWritten, NULL)) 
   if(logLevel ==1)
   log("cannot write to child in write\n",1);

 // Close the pipe handle so the child process stops reading. 
 /*
  if (! CloseHandle(hChildStdinWr)) {
   if(logLevel==1)     
     log("Close pipe failed in write \n");
   ExitProcess(0); 
   }
   */
 } 



 void ReadFromPipe(VOID) 
 { 
   DWORD dwRead, dwWritten; 
  CHAR chBuf[MAX]; 

  // Close the write end of the pipe before reading from the 
  // read end of the pipe. 
  log("reading data from child process \n",1 );
  /*if (!CloseHandle(hChildStdoutWr)) {
      cerr<<"Closing handle failed\n";
  ExitProcess(0); 
      }*/

     // Read output from the child process, and write to parent's STDOUT. 

    for(;;)
     { 
      if( !ReadFile( hChildStdoutRd, chBuf, MAX, &dwRead, 
        NULL) || dwRead == 0) break; 
        if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL)) 
         break; 

        if(logLevel ==1) {
        log(chBuf,1);
          log("\n");
         }
        memset(chBuf,NULL,MAX);
       }
        log("finished reading \n",1);
         } 



       BOOL CreateChildProcess() 
        { 
          TCHAR szCmdline[1024] ;
          if(pool && !submit) {
          sprintf(szCmdline,"program.exe");
         }
         else {    
             sprintf(szCmdline,"command.exe  argument");
             }

             PROCESS_INFORMATION piProcInfo; 
             STARTUPINFO siStartInfo;
             BOOL bFuncRetn = FALSE; 

           // Set up members of the PROCESS_INFORMATION structure. 

                 ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

            // Set up members of the STARTUPINFO structure. 

              ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
            siStartInfo.cb = sizeof(STARTUPINFO); 
             siStartInfo.hStdError = hChildStdoutWr;
            siStartInfo.hStdOutput = hChildStdoutWr;
            siStartInfo.hStdInput = hChildStdinRd;
             siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

               // Create the child process. 

               bFuncRetn = CreateProcess(NULL, 
             szCmdline,     // 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 

           if (bFuncRetn == 0)  {
            ExitProcess(0); 
           }


              return bFuncRetn;
               }



        void execute() {

       SECURITY_ATTRIBUTES saAttr; 
        BOOL fSuccess; 
       // Set the bInheritHandle flag so pipe handles are inherited. 
         saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
          saAttr.bInheritHandle = TRUE; 
          saAttr.lpSecurityDescriptor = NULL; 
       // Get the handle to the current STDOUT. 
         hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
       // Create a pipe for the child process's STDOUT. 
          if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
            ExitProcess(1);
            }
         // Ensure that the read handle to the child process's pipe for STDOUT is not  
            inherited.
       SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
             // Create a pipe for the child process's STDIN. 
         if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {

           ExitProcess(1);
                 }
        // Ensure that the write handle to the child process's pipe for STDIN is not 
                nherited. 
                 SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
             // Now create the child process. 
           fSuccess = CreateChildProcess(host,password,action,username);
          if (! fSuccess) {
        cerr<<"Create process failed";
               ExitProcess(0); 
               }
           CloseHandle(hChildStdinRd);
           CloseHandle(hChildStdoutWr);



              WriteToPipe();
                ReadFromPipe();



                  } 
VOID WriteToPipe(VOID) 
{ 
 DWORD  dwWritten; 
  CHAR chBuf[3];
   sprintf(chBuf,"y\r\n");  
  if(logLevel==1) 
log("trying to write y to child\n",1);
 // Read from a file and write its contents to a pipe. 


    if (! WriteFile(hChildStdinWr, chBuf, 3, 
      &dwWritten, NULL)) 
   if(logLevel ==1)
   log("cannot write to child in write\n",1);

 // Close the pipe handle so the child process stops reading. 
 /*
  if (! CloseHandle(hChildStdinWr)) {
   if(logLevel==1)     
     log("Close pipe failed in write \n");
   ExitProcess(0); 
   }
   */
 } 



 void ReadFromPipe(VOID) 
 { 
   DWORD dwRead, dwWritten; 
  CHAR chBuf[MAX]; 

  // Close the write end of the pipe before reading from the 
  // read end of the pipe. 
  log("reading data from child process \n",1 );
  /*if (!CloseHandle(hChildStdoutWr)) {
      cerr<<"Closing handle failed\n";
  ExitProcess(0); 
      }*/

     // Read output from the child process, and write to parent's STDOUT. 

    for(;;)
     { 
      if( !ReadFile( hChildStdoutRd, chBuf, MAX, &dwRead, 
        NULL) || dwRead == 0) break; 
        if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL)) 
         break; 

        if(logLevel ==1) {
        log(chBuf,1);
          log("\n");
         }
        memset(chBuf,NULL,MAX);
       }
        log("finished reading \n",1);
         } 



       BOOL CreateChildProcess() 
        { 
          TCHAR szCmdline[1024] ;
          if(pool && !submit) {
          sprintf(szCmdline,"program.exe");
         }
         else {    
             sprintf(szCmdline,"command.exe  argument");
             }

             PROCESS_INFORMATION piProcInfo; 
             STARTUPINFO siStartInfo;
             BOOL bFuncRetn = FALSE; 

           // Set up members of the PROCESS_INFORMATION structure. 

                 ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

            // Set up members of the STARTUPINFO structure. 

              ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
            siStartInfo.cb = sizeof(STARTUPINFO); 
             siStartInfo.hStdError = hChildStdoutWr;
            siStartInfo.hStdOutput = hChildStdoutWr;
            siStartInfo.hStdInput = hChildStdinRd;
             siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

               // Create the child process. 

               bFuncRetn = CreateProcess(NULL, 
             szCmdline,     // 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 

           if (bFuncRetn == 0)  {
            ExitProcess(0); 
           }


              return bFuncRetn;
               }



        void execute() {

       SECURITY_ATTRIBUTES saAttr; 
        BOOL fSuccess; 
       // Set the bInheritHandle flag so pipe handles are inherited. 
         saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
          saAttr.bInheritHandle = TRUE; 
          saAttr.lpSecurityDescriptor = NULL; 
       // Get the handle to the current STDOUT. 
         hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
       // Create a pipe for the child process's STDOUT. 
          if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
            ExitProcess(1);
            }
         // Ensure that the read handle to the child process's pipe for STDOUT is not  
            inherited.
       SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
             // Create a pipe for the child process's STDIN. 
         if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {

           ExitProcess(1);
                 }
        // Ensure that the write handle to the child process's pipe for STDIN is not 
                nherited. 
                 SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
             // Now create the child process. 
           fSuccess = CreateChildProcess(host,password,action,username);
          if (! fSuccess) {
        cerr<<"Create process failed";
               ExitProcess(0); 
               }
           CloseHandle(hChildStdinRd);
           CloseHandle(hChildStdoutWr);



              WriteToPipe();
                ReadFromPipe();



                  } 
夜灵血窟げ 2024-09-14 01:54:51

有儿童节目的资源吗?检查它如何读取输入(或在此处发布源代码)。

您的子程序是否可以使用 cmd 输入重定向,例如,如果您执行 echo yes |子程序.exe?

如果没有,则该程序可能使用低级别 控制台函数 进行输入(可能是间接的,例如通过_getch())。在这种情况下,您可能必须使用 WriteConsoleInput 模拟输入。

或者,您的重定向代码可能有错误。发布在这里。

编辑使用WriteConsoleInput的示例:

#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>

static const INPUT_RECORD SimulatedInput [] =
{
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'e'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'c'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'h'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'o'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L' '}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'T'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'E'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'S'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'T'}, 0}},
    {KEY_EVENT, {TRUE, 1, VK_RETURN, 0, {L'\r'}, 0}},
};

int main( int, char*[] )
{
    printf("\n(type 'exit' to exit the subshell)\n");

    // start a command interpreter asynchronously
    intptr_t process_handle = _spawnlp(_P_NOWAIT, "cmd", "/k", "prompt", "SUBSHELL: ", NULL);

    // get own console handle
    HANDLE con_input_handle = GetStdHandle(STD_INPUT_HANDLE);

    // send input to the console
    DWORD n_written;
    WriteConsoleInputW(con_input_handle, SimulatedInput, _countof(SimulatedInput), &n_written);

    // wait for child process to exit
    _cwait(NULL, process_handle, 0);

    return 0;
}

上面的示例必须编译为控制台程序,因为它使用GetStdHandle来获取控制台输入句柄。当父级是控制台应用程序时,子控制台应用程序将与父级共享控制台。如果父级是 GUI 应用程序,因此没有控制台,请使用 AttachConsole 函数在调用 GetStdHandle 之前附加到子进程控制台,然后调用 FreeConsole 完成后。

Do you have sources of the child program? Check how it reads its input (or post the source here).

Does your child program work with cmd input redirection, e.g. if you do echo yes | childprogram.exe?

If not, chances are that the program uses low level console functions to do its input (maybe indirectly, e.g. via _getch()). In this case you may have to use WriteConsoleInput to simulate input.

Or, there may be a mistake in your redirection code. Post it here.

EDIT A sample of using WriteConsoleInput:

#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>

static const INPUT_RECORD SimulatedInput [] =
{
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'e'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'c'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'h'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'o'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L' '}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'T'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'E'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'S'}, 0}},
    {KEY_EVENT, {TRUE, 1, 0, 0, {L'T'}, 0}},
    {KEY_EVENT, {TRUE, 1, VK_RETURN, 0, {L'\r'}, 0}},
};

int main( int, char*[] )
{
    printf("\n(type 'exit' to exit the subshell)\n");

    // start a command interpreter asynchronously
    intptr_t process_handle = _spawnlp(_P_NOWAIT, "cmd", "/k", "prompt", "SUBSHELL: ", NULL);

    // get own console handle
    HANDLE con_input_handle = GetStdHandle(STD_INPUT_HANDLE);

    // send input to the console
    DWORD n_written;
    WriteConsoleInputW(con_input_handle, SimulatedInput, _countof(SimulatedInput), &n_written);

    // wait for child process to exit
    _cwait(NULL, process_handle, 0);

    return 0;
}

The sample above has to be compiled as a console program, because it uses GetStdHandle to obtain console input handle. When parent is a console app, child console app will share the console with parent. If parent is a GUI app and thus has no console, use AttachConsole function to attach to the child process console before calling GetStdHandle, then call FreeConsole when finished with it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文