Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3902545
  • 博文数量: 534
  • 博客积分: 10470
  • 博客等级: 上将
  • 技术积分: 4800
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-26 14:08
文章分类

全部博文(534)

文章存档

2021年(1)

2019年(1)

2017年(1)

2016年(2)

2013年(2)

2012年(10)

2011年(43)

2010年(10)

2009年(17)

2008年(121)

2007年(253)

2006年(73)

分类:

2007-09-28 16:42:08

/*
这段代码主要来源:

原理:
   [pipe 1] -> [cmd.exe] => [pipe 2]

其中cmd.exe为新创建的进程,该进程有一个输入,一个输出,一个错误输出。 在这里将标准输出和错误输出都输入到一个管道(pipe 2)里面的。
在这个小事例中使用了两个管道。

pipe 1 的作用主要是负责cmd.exe的输入工作的, 它从一个文件中读入一部分数据通过管道1(pipe 1)进入到cmd.exe的输入中。
pipe 2 的作用就是将cmd.exe的输出作为管道(pipe 2)的输入,pipe 2 的输出最终是输出到标准输出上,我们就可以看到直接的结果了。

安装完VC, 设置完PATH环境变量。 我把该文件命名为:pipe.c

编译: cl pipe1.c

自己新件一个文本文件: c:\a.txt
文件内容为:
dir
type a.txt

执行: pipe1 c:\a.txt
看看结果是什么,还是挺有意识的哦。

管道在进程间通信的时候用的还是挺多的。在做这个小测试前最好看看管道的原理知识比较好。
其实这个小测试写的不是很好, 很多该做的错误处理没有做, 但还是可以用来做管道学习用的。
 */

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

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, hInputFile, hStdout;

BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPSTR);

int main(int argc, TCHAR *argv[])
{
   SECURITY_ATTRIBUTES saAttr;
   BOOL fSuccess;

// Set the bInheritHandle flag so pipe handles are inherited.

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

// Get the handle to the current STDOUT.

   hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Create a pipe for the child process's STDOUT.

   if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
      ErrorExit("Stdout pipe creation failed\n");

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

   SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);

// Create a pipe for the child process's STDIN.

   if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
      ErrorExit("Stdin pipe creation failed\n");

// Ensure the write handle to the pipe for STDIN is not inherited.

   SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0);

// Now create the child process.

   fSuccess = CreateChildProcess();
   if (!fSuccess)
      ErrorExit("Create process failed with");

// Get a handle to the parent's input file.

   if (argc == 1)
      ErrorExit("Please specify an input file");

   printf("\nContents of %s:\n\n", argv[1]);

   hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
   if (hInputFile == INVALID_HANDLE_VALUE)
      ErrorExit("CreateFile failed");

// Write to pipe that is the standard input for a child process.

   WriteToPipe();

// Read from pipe that is the standard output for child process.

   ReadFromPipe();

   return 0;
}

BOOL CreateChildProcess()
{
   TCHAR szCmdline[] = TEXT("cmd");
   PROCESS_INFORMATION piProcInfo;
   STARTUPINFO siStartInfo;
   BOOL bFuncRetn = FALSE;

// Set up members of the PROCESS_INFORMATION structure.

   ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));

// Set up members of the STARTUPINFO structure.

   ZeroMemory(&siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO);
   siStartInfo.hStdError = hChildStdoutWr;
   siStartInfo.hStdOutput = hChildStdoutWr;
   siStartInfo.hStdInput = hChildStdinRd;
   siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

// Create the child process.

   bFuncRetn = CreateProcess(NULL,
      szCmdline, // command line

      NULL, // process security attributes

      NULL, // primary thread security attributes

      TRUE, // handles are inherited

      0, // creation flags

      NULL, // use parent's environment

      NULL, // use parent's current directory

      &siStartInfo, // STARTUPINFO pointer

      &piProcInfo); // receives PROCESS_INFORMATION


   if (bFuncRetn == 0)
      ErrorExit("CreateProcess failed\n");
   else
   {
      CloseHandle(piProcInfo.hProcess);
      CloseHandle(piProcInfo.hThread);
      return bFuncRetn;
   }

   return (TRUE);
}

VOID WriteToPipe(VOID)
{
   DWORD dwRead, dwWritten;
   CHAR chBuf[BUFSIZE];

// Read from a file and write its contents to a pipe.

   for (;;)
   {
      if (!ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0)
          break;

      if (!WriteFile(hChildStdinWr, chBuf, dwRead, &dwWritten, NULL))
          break;
   }

// Close the pipe handle so the child process stops reading.

   if (!CloseHandle(hChildStdinWr))
      ErrorExit("Close pipe failed\n");
}

VOID ReadFromPipe(VOID)
{
   DWORD dwRead, dwWritten;
   CHAR chBuf[BUFSIZE];

// Close the write end of the pipe before reading from the read end of the pipe.

   if (!CloseHandle(hChildStdoutWr))
      ErrorExit("Closing handle failed");

// Read output from the child process, and write to parent's STDOUT.

   for (;;)
   {
      if (!ReadFile(hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0)
          break;

      if (!WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL))
          break;
   }
}

VOID ErrorExit (LPSTR lpszMessage)
{
   fprintf(stderr, "%s\n", lpszMessage);
   ExitProcess(0);
}

阅读(4234) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~