2017-02-08 10 views
1

EDIT:Harry Johnstonの提案によると、Child_In_Writeハンドルを閉じることでした。
少し皮肉なことに、以前Child_In_Readハンドルを閉じることを試みました。これは機能しません。書き込みハンドルは閉じていなければならない唯一のハンドルです。私が作るしようとしているツールについては作成された子プロセスによってリダイレクトされたstdinパイプが無視される

、私は標準入力を通じてプロセスを起動し、それにデータを与えることができるようにする必要があります - 私は

十分なシンプルなアイデアをパイプでコマンドラインを経由して、それを呼び出したかのように。 I've primarily I've followed this guide from Microsoft and got things "working". 私自身のテストプログラムでは、stdinから読み込めます。しかし、例えば猫のような他のプログラムを使うと、入力を待っているかのように、何もしません。ここ

The full repo is here.

関連するコードビットである:

はパイプを初期化します。

ちょうど初期化されたパイプに書き込み、プロセスを開始します。正常に動作するように見える

// From Cao/Main.cpp 
    // Write to the processes' standard in. 
    { 
     DWORD inBytesWritten = 0; 
     bool writeSuccess = 
      WriteFile(
       Child_In_Write, 
       text,    // Simple char array. 
       text_numBytes, 
       &inBytesWritten, 
       NULL); 
     if (!writeSuccess) 
     { 
      // @logging log error. 
      printf("Could not write to child's standard in!\n"); 
      goto textData_cleanup; 
     } 
    } 

    // Create the child process. 
    { 
     STARTUPINFO startupInfo = { 0 }; 
     startupInfo.cb   = sizeof(startupInfo); 
     startupInfo.hStdInput = Child_In_Read; 
     startupInfo.hStdError = Child_Out_Write; 
     startupInfo.hStdOutput = Child_Out_Write; 
     startupInfo.dwFlags = STARTF_USESTDHANDLES; 

     bool createProcessSuccess = CreateProcessW(
      NULL, 
      commandLine, 
      NULL, 
      NULL, 
      true, 
      0, 
      NULL, 
      NULL, 
      &startupInfo, 
      &ChildProcInfo);   
     if (!createProcessSuccess) 
     { 
      printf("Could not start child process with command line: %ls", commandLine); 
      goto textData_cleanup; 
     } 

     isChildRunning = true; 
     ModifyMenu(IconMenu, IconMenu_RunCancel, MF_BYCOMMAND, IconMenu_RunCancel, L"Cancel"); 

     // newHandle is always 0x00000000 so I'm assuming I don't need to clean it up. 
     HANDLE newHandle; 
     RegisterWaitForSingleObject(&newHandle, ChildProcInfo.hProcess, LaunchedProcessExitedOrCancelled, NULL, INFINITE, WT_EXECUTEONLYONCE); 
    } 

私の読書コード:

// From Echoer/Main.cpp 
printf("via stdin:\n"); 
{ 
    const int readBuffer_size = 5000; 
    char *readBuffer[readBuffer_size]; 

    { 
     HANDLE standardIn = GetStdHandle(STD_INPUT_HANDLE); 
     DWORD bytesRead = 0; 

     bool readSuccess = 
      ReadFile(
       standardIn, 
       readBuffer, 
       readBuffer_size, 
       &bytesRead, 
       NULL); 
     if (!readSuccess) 
     { 
      printf("Could not read from standard in!\n"); 
     } 

     CloseHandle(standardIn); 
    } 

    printf("%s", readBuffer); 
} 

私は「ボールが転がり取得」するために送信する必要がある何かが足りないのですか? 「\ r \ n」かそのようなものを追加する必要がありますか?シェルはこれをどのように管理していますか?

+0

あなたは練習のためにそれを行う場合それは大丈夫です。あなたが物事を完了したい場合は、boost.process(公式のブーストの一部ではない)を使用して自分自身の時間を節約:) –

+0

@HarryJohnstonパイプを閉じた!そんなにありがとう、これは私を狂ってしまった!私は私のポストを更新します。私はあなたに十分に値する点を与えることができるように答えるべきです。 –

答えて

0

catを含む一部のアプリケーションは、終了する前に標準入力でファイルの終わりを待機します。これは、パイプの端を閉じることで実現できます。

(あなたはまた、パイプのエンドへのハンドルが子供によって、または任意の他のプロセスによって継承されていませんが、あなたのコードは、すでにこれを正しく扱うことを確信しなければなりません。)

関連する問題