ОБНОВЛЕНИЕ Вопрос: Итак, я смог создать процесс и собрать программы для компиляции. Однако я столкнулся с новой проблемой. Когда я пытаюсь передать программу Source в программу Filter. Кажется, что он не подает ни один вход для программы раковины. Сообщение об ошибке отсутствует. Я также тестировал всю свою автономную программу, используя оператор трубы в Windows 'cmd.Создать процесс и анонимный канал
Я пытаюсь сделать этот небольшой проект, чтобы узнать об анонимной трубе и создать процесс. Я создал 3 небольшие автономные программы, называемые Source, Filter и Sink. Эти 3 уже скомпилированы и работают нормально. Ниже приведены описания для 3 автономных программ.
Источник: получает исходное текстовое имя файла из своей командной строки, открывает файл и считывает и копирует содержимое файла по одному символу за раз непосредственно до стандартного вывода (stdout). Когда файл был скопирован, Source завершает работу (закрывая все открытые дескрипторы файла).
Программа фильтра не использует параметры командной строки имени файла. Вместо этого фильтр считывает текстовый файл со стандартного ввода (stdin) и записывает на стандартный вывод (stdout) копию ввода со всеми прописными буквами, преобразованными в нижний регистр. Фильтр специально должен быть предназначен для чтения одного символа, преобразования его, вывода его и последующего цикла до тех пор, пока входящие данные не будут завершены.
Программа Sink получает имя файла текстового файла назначения из своей командной строки, открывает файл для записи, а затем считывает символы по одному из стандартного входного файла (stdin) и записывает каждый входящий символ непосредственно в файл приемника ,
Далее я запускаю программу основного драйвера отдельно, которая создает 2 канала и создает 3 независимых дочерних элемента с входами и выходами, сконфигурированными для выполнения указанного параллельного выполнения и потока данных. Что-то вроде этого:
- srcfile -> Источник -> Pipe1 -> Фильтр -> Pipe2 -> Раковина -> DestFile
Программа водитель требует параметров линии 2 команды:
C:\> Driver.exe srcfile destfile
где srcfile это существующие данные текстового файла, и destfile - имя файла нового целевого файла, который должен быть создан приложением Sink.
Вот мой код для программы водителя. Это еще не закончено. Но при попытке создать процесс для исходной программы я столкнулся с икотой.
ОБНОВЛЕНО КОД:
#include <windows.h>
#include <WinBase.h>
#include <stdio.h>
#define DELAY_A_WHILE() {volatile long j; for(j = 1; j< 10000; j++) ; }
int main(int argc, char *argv[])
{
HANDLE hPipeRead, hPipeWrite, hPipeRead2, hPipeWrite2;
STARTUPINFO StartupInfoSource;
STARTUPINFO StartupInfoFilter;
STARTUPINFO StartupInfoSink;
PROCESS_INFORMATION ProcInfoSource;
PROCESS_INFORMATION ProcInfoFilter;
PROCESS_INFORMATION ProcInfoSink;
SECURITY_ATTRIBUTES PipeAttributes;
SECURITY_ATTRIBUTES PipeAttributes2;
char cmdline[200];
PipeAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
PipeAttributes.lpSecurityDescriptor = NULL; //ignore
PipeAttributes.bInheritHandle = TRUE; //child can inherit
//Create first pipe
if (!CreatePipe(&hPipeRead, &hPipeWrite, &PipeAttributes, 0)) {
fprintf(stderr, "Error creating pipe: %d\n", GetLastError());
exit(1);
}
sprintf_s(cmdline, 200, "Source.exe %s", argv[1]);
printf("Create process: %s\n", cmdline);
GetStartupInfo(&StartupInfoSource);
StartupInfoSource.dwFlags = StartupInfoSource.dwFlags | STARTF_USESTDHANDLES;
//Mapping
StartupInfoSource.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
StartupInfoSource.hStdOutput = hPipeWrite;
StartupInfoSource.hStdError = GetStdHandle(STD_ERROR_HANDLE);
if (!CreateProcess(
NULL, cmdline, NULL, NULL,
TRUE,
CREATE_NEW_CONSOLE, NULL, NULL,
&StartupInfoSource,
&ProcInfoSource))
{
fprintf(stderr, "Error creating child process: %d",GetLastError());
exit(1);
}
CloseHandle(hPipeWrite);
CloseHandle(ProcInfoSource.hProcess);
CloseHandle(ProcInfoSource.hThread);
PipeAttributes2.nLength = sizeof(SECURITY_ATTRIBUTES);
PipeAttributes2.lpSecurityDescriptor = NULL; //ignore
PipeAttributes2.bInheritHandle = TRUE; //child can inherit
//Create Second Pipe
if (!CreatePipe(&hPipeRead2, &hPipeWrite2, &PipeAttributes2, 0)) {
fprintf(stderr, "Error creating pipe: %d\n", GetLastError());
exit(1);
}
GetStartupInfo(&StartupInfoFilter);
StartupInfoFilter.dwFlags = StartupInfoFilter.dwFlags | STARTF_USESTDHANDLES;
//Mapping
StartupInfoFilter.hStdInput = hPipeRead;
StartupInfoFilter.hStdOutput = hPipeWrite2;
StartupInfoFilter.hStdError = GetStdHandle(STD_ERROR_HANDLE);
sprintf_s(cmdline, 200, "Filter.exe");
printf("Create process: %s\n", cmdline);
//Filter
GetStartupInfo(&StartupInfoFilter);
if (!CreateProcess(
NULL, cmdline, NULL, NULL,
TRUE,
CREATE_NEW_CONSOLE, NULL, NULL,
&StartupInfoFilter,
&ProcInfoFilter))
{
fprintf(stderr, "Error creating child process: %d", GetLastError());
exit(1);
}
// int exitStatus;
// GetExitCodeProcess(ProcInfoFilter.hProcess, &exitStatus);
CloseHandle(hPipeRead);
CloseHandle(hPipeWrite2);
CloseHandle(ProcInfoFilter.hProcess);
CloseHandle(ProcInfoFilter.hThread);
GetStartupInfo(&StartupInfoSink);
StartupInfoSink.dwFlags = StartupInfoSink.dwFlags | STARTF_USESTDHANDLES;
//Mapping
StartupInfoSink.hStdInput = hPipeRead2;
StartupInfoSink.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
StartupInfoSink.hStdError = GetStdHandle(STD_ERROR_HANDLE);
sprintf_s(cmdline, 200, "Sink.exe %s", argv[2]);
printf("Create process: %s\n", cmdline);
GetStartupInfo(&StartupInfoSink);
if (!CreateProcess(
NULL, cmdline, NULL, NULL,
TRUE,
CREATE_NEW_CONSOLE, NULL, NULL,
&StartupInfoSink,
&ProcInfoSink))
{
fprintf(stderr, "Error creating child process: %d", GetLastError());
exit(1);
}
CloseHandle(hPipeRead2);
CloseHandle(ProcInfoSink.hProcess);
CloseHandle(ProcInfoSink.hThread);
return 0;
}
Программа компилируется нормально. Однако, когда он пытается создать Process, он всегда терпит неудачу и завершается. Значение cmdline
при анализе - «Source.exe test.txt», что я и использовал для выполнения автономной исходной программы. Может кто-нибудь объяснить, почему мой CreateProcess
не удается? Это потому, что я анализирую неправильный параметр?
Итак, вы говорите, что «CreateProcess» терпит неудачу? Затем вы должны изучить код ошибки, возвращаемый 'GetLastError'. Кстати, правильно ли вы передаете «STARTUPINFO» вызывающего процесса? Это передать дескрипторы stdin и stdout? –
Когда я пытаюсь отлаживать, программа всегда выполняет кусок кода внутри, если (! CreateProcess()), который должен печатать ошибку, когда не удается создать и выйти из программы. –