前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CreatePipe()等函数创建管道来操纵控制台

CreatePipe()等函数创建管道来操纵控制台

作者头像
全栈程序员站长
发布2022-09-14 19:05:01
2810
发布2022-09-14 19:05:01
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

#include <stdio.h>

#include <windows.h>

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,

hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,

hInputFile, hStdout;

BOOL CreateChildProcess( VOID );

VOID WriteToPipe( VOID );

VOID ReadFromPipe( VOID );

VOID ErrorExit( LPTSTR );

VOID ErrMsg( LPTSTR , BOOL );

DWORD main( int argc, char *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" );

// Create noninheritable read handle and close the inheritable read

// handle.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,

GetCurrentProcess(), &hChildStdoutRdDup , 0,

FALSE,

DUPLICATE_SAME_ACCESS);

if ( !fSuccess )

ErrorExit( "DuplicateHandle failed" );

CloseHandle(hChildStdoutRd);

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

if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))

ErrorExit( "Stdin pipe creation failed\n" );

// Duplicate the write handle to the pipe so it is not inherited.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,

GetCurrentProcess(), &hChildStdinWrDup, 0,

FALSE, // not inherited

DUPLICATE_SAME_ACCESS);

if (! fSuccess)

ErrorExit( "DuplicateHandle failed" );

CloseHandle(hChildStdinWr);

// Now create the child process.

fSuccess = CreateChildProcess();

if (! fSuccess)

ErrorExit( "Create process failed" );

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

if (argc == 1)

ErrorExit( "Please specify an input file" );

hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);

if (hInputFile == INVALID_HANDLE_VALUE)

ErrorExit( "CreateFile failed\n" );

// 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()

{

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,

"child" , // 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" );

else

{

CloseHandle(piProcInfo.hProcess);

CloseHandle(piProcInfo.hThread);

return bFuncRetn;

}

}

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(hChildStdinWrDup, chBuf, dwRead,

&dwWritten, NULL)) break ;

}

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

if (! CloseHandle(hChildStdinWrDup))

ErrorExit( "Close pipe failed" );

}

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( "CloseHandle failed" );

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

for (;;)

{

if ( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,

NULL) || dwRead == 0) break ;

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

break ;

}

}

VOID ErrorExit ( LPTSTR lpszMessage)

{

fprintf (stderr, "%s\n" , lpszMessage);

ExitProcess(0);

}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/159417.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档