Тупик при использовании ReadFile и WriteFile - PullRequest
0 голосов
/ 09 декабря 2018

Я работаю над школьным проектом, в котором я пытаюсь показать в StdOut дочернего процесса, что было написано в StdIn родителя;и наоборот, т. е. показать, что было написано на дочернем процессе StdIn на родительском StdOut, но я зашел в тупик с операциями ReadFile и WriteFile.

Из того, что я мог собрать во время исследования этой темы, этообычная проблема при использовании синхронных каналов.

Следует ли синхронизировать операцию чтения и записи по событию?Вы предлагаете другой подход?Любые предложения будут оценены, спасибо заранее.

Parent.cpp

   #include <windows.h>
   #include <iostream>
   #include <stdio.h>

   //read handle pipe1
   HANDLE r1 = NULL;

   //write handle pip1
   HANDLE w1 = NULL;

   //read handle pipe2
   HANDLE r2 = NULL;

   //write handle for pipe2
   HANDLE w2 = NULL;

   #define BUFSIZE 4096

   void CreateChildProcess() {
       TCHAR applicationName[] = TEXT("Child");
       PROCESS_INFORMATION pi;
       STARTUPINFO si;
       BOOL success = FALSE;

       ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
       ZeroMemory(&si, sizeof(STARTUPINFO));

       si.cb = sizeof(STARTUPINFO);
       si.hStdError = w1;
       si.hStdOutput = w1;
       si.hStdInput = r2;
       si.dwFlags |= STARTF_USESTDHANDLES;


       success = CreateProcess(NULL, applicationName, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

       if (!success) {
           printf("Error creating child process \n");
       }
       else {

           printf("Child process successfuly created \n");
           CloseHandle(pi.hProcess);
           CloseHandle(pi.hThread);
       }
   }
   void WriteToPipe() {
       DWORD read, written;
       CHAR chBuf[BUFSIZE];
       BOOL success = FALSE;

       HANDLE pStdIn = GetStdHandle(STD_INPUT_HANDLE);

       for (;;)
       {
           success = ReadFile(pStdIn, chBuf, BUFSIZE, &read, NULL);
           if (!success || read == 0) break;

           success = WriteFile(w2, chBuf, read, &written, NULL);
           if (!success) break;
       }
   }

   void ReadFromPipe() {
       DWORD read, written;
       CHAR chBuf[BUFSIZE];
       BOOL success = FALSE;

       HANDLE pStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

       for (;;)
       {
           success = ReadFile(r1, chBuf, BUFSIZE, &read, NULL);
           if (!success || read == 0) break;

           success = WriteFile(pStdOut, chBuf, read, &written, NULL);
           if (!success) break;
       }
   }

   int main()
   {

       DWORD dRead, dWritten;
       CHAR chBuf[BUFSIZE];
       BOOL bSuccess = FALSE;

       SECURITY_ATTRIBUTES secAttr;
       secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
       secAttr.bInheritHandle = TRUE;
       secAttr.lpSecurityDescriptor = NULL;

       printf("Creating first pipe\n");
       if (!CreatePipe(&r1, &w1, &secAttr, 0)) {
           printf("\nError creating first pipe\n");
       }
       printf("Creating second pipe\n");
       if (!CreatePipe(&r2, &w2, &secAttr, 0)) {
           printf("Error creating second pipe \n");
       }


       if (!SetHandleInformation(r1, HANDLE_FLAG_INHERIT, 0)) {
           printf("r1 SetHandleInformation \n");
       }
       if (!SetHandleInformation(w2, HANDLE_FLAG_INHERIT, 0)) {
           printf("w2 SetHandleInformation \n");
       }


       printf("\nCreating child process..... \n");
       CreateChildProcess();

       WriteToPipe();
       ReadFromPipe();

       return 0;
   }

Child.cpp

   #include <windows.h>
   #include <stdio.h>
   #include "pch.h"

   #define BUFSIZE 4096

   int main()
   {
       DWORD dRead, dWritten;
       CHAR chBuf[BUFSIZE];
       BOOL success = FALSE;
       HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
       HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);


       if (stdIn == INVALID_HANDLE_VALUE || stdOut == INVALID_HANDLE_VALUE) {
           ExitProcess(1);
       }

       for (;;) {
           success = ReadFile(stdIn, chBuf, BUFSIZE, &dRead, NULL);
           if (!success || dRead == 0) break;
success = WriteFile(stdOut, chBuf, dRead, &dWritten, NULL);
           if (!success) break;
       }

       return 0;
   }

1 Ответ

0 голосов
/ 14 декабря 2018

Вы не сможете показать, что было написано на дочернем процессе StdIn на родительском StdOut, так как дескриптор дочернего stdIn был установлен на "r2".Так что вы не можете ничего вставить в дочерний процесс вручную.Я предлагаю использовать namepipe , чтобы дочерний дескриптор std не смешивался с другими дескрипторами канала.

для (;;) равно while (1), и ReadFile () выиграл 'Возврат до получения данных, поэтому, если не возникает исключение (исключая входящие данные), цикл никогда не прервется, и код не перейдет к ReadFromPipe ();

Используйте режим перекрытия:namepipe Или Попробуйте создать 2 потока и 2 namepipes, одну для чтения из namepipe, затем распечатать, а другую для чтения из stdin и затем написать для namepipe (в обоих процессах).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...