更新问题:所以我已经能够创建流程并将程序编译。但是,我遇到了一个新问题。当我尝试将Source程序传递给Filter程序时。它似乎没有为sink程序提供任何输入。没有错误消息。我还使用Windows“cmd”中的管道运算符测试了我的所有独立程序。
我正在尝试这个小项目来了解匿名管道和创建流程。我创建了3个名为Source,Filter和Sink的小型独立程序。这三个已编译并运行正常。以下是3个独立程序的说明。
Source:从命令行获取源文本文件文件名,打开文件,并一次一个字符地读取和复制文件内容到标准输出(stdout)。复制文件后,Source将终止(关闭所有打开的文件句柄)。
过滤程序不使用任何文件名命令行参数。相反,Filter从标准输入(stdin)读取文本文件,并将标准输出(stdout)写入输入的副本,所有大写字母都转换为小写。特别是过滤器必须设计为读取一个字符,转换它,输出它,然后循环,直到输入数据结束。
Sink程序从其命令行获取目标文本文件文件名,打开文件进行写入,然后从标准输入文件(stdin)一次读取一个字符,并将每个传入字符直接写入目标接收器文件。
接下来,我将分别驱动一个主驱动程序,创建2个管道,并产生3个独立子项,其输入和输出配置为执行指示的并发执行和数据流。像这样:
驱动程序将需要2个命令行参数:
C:\> Driver.exe srcfile destfile
其中srcfile是现有数据文本文件,destfile是由Sink应用程序创建的新目标文件的文件名。
这是我的驱动程序代码。它尚未完成。但是在尝试为Source程序创建进程时遇到了打嗝。
更新代码:
#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
失败了吗?是因为我解析了错误的参数吗?
答案 0 :(得分:2)
我在这里看到的唯一问题是Source.exe应用程序可能不在Driver.exe所在的同一目录中。我尝试了你的代码,这是CreateProcess失败的唯一情况。
答案 1 :(得分:-1)
我弄明白了为什么。我的项目的属性是使用Unicode字符集。当我切换到多字节字符集时,它工作正常。