+7(960) 250-82-68 sergey@mirossa.ru


button
button
button
button
button


 
Статьи
 

Создание канала, получение данных из дочернего процесса

https://docs.microsoft.com/en-us/windows/desktop/procthread/creating-a-child-process-with-redirected-input-and-output
https://docs.microsoft.com/ru-ru/windows/desktop/SysInfo/handle-inheritance
https://docs.microsoft.com/ru-ru/windows/desktop/api/processthreadsapi/ns-processthreadsapi-_startupinfoa
https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa

файл news_opener.c

//Создаем канал, создаем дочерний процесс (его стандартный вывод связан с каналом), ждём завершения процесса, читаем данные из канала.

//компиляция C-Free
//cd "C:\Program Files (x86)\C-Free 5\mingw\bin"
//gcc.exe news_opener.c -o news_opener.exe


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <windows.h>

//#define BUFSIZE 4096
#define BUFSIZE 100


void ReadFromPipe(HANDLE hReadPipe);

void error(char *msg)
{
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(1);
}


int main(){


// Set the bInheritHandle flag so pipe handles are inherited.
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;



/////Создается канал
// PHANDLE hReadPipe,
// hWritePipe;
HANDLE hReadPipe = NULL,
hWritePipe = NULL;

MessageBox(NULL, "debug1", TEXT("Error"), MB_OK);
// если вместо &saAttr NULL , то ошибка при создании процесса
if ( ! CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0)){
MessageBox(NULL, "debug1.1", TEXT("Error"), MB_OK);
error("Не могу создать канал");
}

MessageBox(NULL, "debug2", TEXT("Error"), MB_OK);

// Ensure the read handle to the pipe for STDOUT is not inherited.

// if ( ! SetHandleInformation(hReadPipe, HANDLE_FLAG_INHERIT, 0) )
// error(TEXT("Stdout SetHandleInformation"));
////



//pid_t pid = fork();
STARTUPINFO cif;
ZeroMemory(&cif,sizeof(STARTUPINFO));
cif.cb = sizeof(STARTUPINFO);
//cif.hStdError = hWritePipe;
cif.hStdOutput = hWritePipe;
//cif.hStdInput = g_hChildStd_IN_Rd; //не меняем
cif.dwFlags |= STARTF_USESTDHANDLES;

PROCESS_INFORMATION pi;

printf("ok0 - Parent process ");

// C:\Windows\system32\notepad.exe C:\vsyakoe\1.txt
if (CreateProcess("imitaciya.exe",
//NULL, //каждый параметр с пробелами(путь) в Кавычках. тогда работает.
"imitaciya.exe parameter1", //передача параметра в дочерний процесс
NULL,NULL,
TRUE, // handles are inherited
0,
// переменные окружения для дочернего процесса
//NULL,
"RSS_FEED=http://rss.cnn.com/rss/edition_technology.rss\0\0",
NULL,&cif,&pi)==TRUE){

WaitForSingleObject(pi.hProcess, INFINITE); //ожидание завершения
CloseHandle(hWritePipe); // закрытие конца канала, куда дочерний процесс пишет данные. Если не закрыть, то зависнем на ReadFile( hReadPipe...


MessageBox(NULL, "debug6", TEXT("Error"), MB_OK);

ReadFromPipe(hReadPipe);

MessageBox(NULL, "debug9", TEXT("Error"), MB_OK);



printf("\nok1 - Parent process ");

}
//даже, если задаем имя приложения в первом параметре, то его нужно дублировать во втором параметре.

else
{
printf("err1 ");
//TerminateProcess(pi.hProcess,NO_ERROR); // убрать процесс
}
MessageBox(NULL, "debug3", TEXT("Error"), MB_OK);


return 0;
}

void ReadFromPipe(HANDLE hReadPipe)

// Read output from the child process's pipe for STDOUT
// and write to the parent process's pipe for STDOUT.
// Stop when there is no more data.
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

for (;;)
{
Sleep(2000);

MessageBox(NULL, "debug10", TEXT("Error"), MB_OK);

//MessageBox(NULL, "debug4", TEXT("Error"), MB_OK);

bSuccess = ReadFile( hReadPipe, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 ) break;

MessageBox(NULL, "debug7", TEXT("Error"), MB_OK);

bSuccess = WriteFile(hParentStdOut, chBuf,
dwRead, &dwWritten, NULL);

Sleep(2000);



if (! bSuccess ) break;
}
MessageBox(NULL, "debug8", TEXT("Error"), MB_OK);
}

файл imitaciya.c

//выводит 1-й параметр и переменную окружения (set RSS_FEED=sdfdfsd), переданные из родительского процесса. И выводит тестовый текст в канал.



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

//cd "C:\Program Files (x86)\C-Free 5\mingw\bin"
// set RSS_FEED=sdfdfsd
//mingw32-gcc.exe imitaciya.c -o imitaciya.exe

int main(int argc, char * argv[])
{
SetConsoleCP(1251); // На ввод
SetConsoleOutputCP(1251); //На вывод.

char * w = getenv("RSS_FEED");

char * c = argv[argc - 1];

printf("Child Process\n");
printf("%s %s\n", c, w);

fprintf(stdout, "The film will follow the story of a reporter who develops an emotional bond with Rogers while profiling him for a magazine, according to director Marielle Heller, who spoke to Entertainment Weekly about the film earlier this year.");

//MessageBox(NULL, "debug5", TEXT("Error"), MB_OK);
fprintf(stdout, "\n\nThe end.");
//MessageBox(NULL, "debug11", TEXT("Error"), MB_OK);

return 0;
}

to be continued...