15,471
社区成员
发帖
与我相关
我的任务
分享
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
//句柄说明
// {Parent Write}-> {g_hChildStd_IN_Wr <-管道-> g_hChildStd_IN_Rd} -> {Child STDINPUT}
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
// {Parent Read}<- {g_hChildStd_OUT_Rd <-管道-> g_hChildStd_OUT_Wr} ->{ Child STDOUTPUT}
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
//产生子进程
void CreateChildProcess(void);
//错误显示
void ErrorExit(PTSTR);
//写入管道
void WriteToPipe(char * chBuf )
{
DWORD dwWritten = 0;
BOOL bSuccess = FALSE;
bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, strlen(chBuf), &dwWritten, NULL);
if ( ! bSuccess ) ErrorExit(TEXT("WriteToPipe() "));
}
//从管道中读数据
void ReadFromPipe(char * chBuf )
{
DWORD dwRead = 0;
BOOL bSuccess = FALSE;
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, sizeof(chBuf)-1, &dwRead, NULL);
if( ! bSuccess ) ErrorExit(TEXT("ReadFromPipe() "));
chBuf[dwRead] ='\0';
}
int _tmain(int argc, TCHAR *argv[])
{
printf("\n->Start of parent execution.\n");
// 管道产生
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE; //管道句柄可继承
saAttr.lpSecurityDescriptor = NULL;
//产生一个用于子进程STDOUT的管道
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
ErrorExit(TEXT("StdoutRd CreatePipe"));
// 设置 用于子进程STDOUT的管道 的读取端不可继承
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdout SetHandleInformation"));
// 为子进程的输出重定向做准备
HANDLE hOriginalStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if ( !SetStdHandle(STD_OUTPUT_HANDLE, g_hChildStd_OUT_Wr))
{
ErrorExit(TEXT("Stdout SetStdHandle"));
}
// 产生一个用于子进程STDIN的管道
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
ErrorExit(TEXT("Stdin CreatePipe"));
// 设置 用于子进程STDIN的管道 的写入端不可继承
if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
ErrorExit(TEXT("Stdin SetHandleInformation"));
// 为子进程的输入重定向做准备
HANDLE hOriginalStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (!SetStdHandle(STD_INPUT_HANDLE, g_hChildStd_IN_Rd))
{
ErrorExit(TEXT("Stdin SetStdHandle"));
}
//产生子进程
CreateChildProcess();
// 回复正常输入输出
if (!SetStdHandle(STD_OUTPUT_HANDLE, hOriginalStdOut))
{
ErrorExit(TEXT("Stdout SetStdHandle huifu"));
}
// else
//本想在这里关闭该句柄,但是关闭之后发现父进程无法输出
// CloseHandle(hOriginalStdOut);
if (!SetStdHandle(STD_INPUT_HANDLE, hOriginalStdIn))
{
ErrorExit(TEXT("Stdin SetStdHandle"));
}
//else
//{//本想在这里关闭该句柄,但是关闭之后发现父进程无法输入
// CloseHandle(hOriginalStdIn);
//}
// 管道测试
// 1)从父进程输入一串字符串放in里面
// 2) 写in中的字符串到管道
// 3) 从管道中读取进过子进程处理过的字符串
// 4) 在父进程中输出,显示到控制台
//
char in[256];
char out[256];
char message1[] ="请输入:";
char message2[] ="管道中是:";
printf( "开始管道测试\n");
for(;;)
{
puts(message1);
gets(in); // 1)从父进程输入一串字符串放in里面
WriteToPipe(in); // 2) 写in中的字符串到管道
ReadFromPipe(out);// 3) 从管道中读取进过子进程处理过的字符串
puts(message2);
puts(out); // 4) 在父进程中输出,显示到控制台
}
//释放句柄
if(g_hChildStd_IN_Rd != NULL)
{
CloseHandle(g_hChildStd_IN_Rd);
g_hChildStd_IN_Rd = NULL;
}
if(g_hChildStd_IN_Wr != NULL)
{
CloseHandle(g_hChildStd_IN_Wr);
g_hChildStd_IN_Wr = NULL;
}
if(g_hChildStd_OUT_Rd != NULL)
{
CloseHandle(g_hChildStd_OUT_Rd);
g_hChildStd_OUT_Rd = NULL;
}
if(g_hChildStd_OUT_Wr != NULL)
{
CloseHandle(g_hChildStd_OUT_Wr);
g_hChildStd_OUT_Wr = NULL;
}
CloseHandle(hOriginalStdOut);
CloseHandle(hOriginalStdIn);
return 0;
}
void CreateChildProcess()
// Create a child process that uses the previously created pipes for STDIN and STDOUT.
{
TCHAR szCmdline[]=TEXT("child\\Debug\\child.exe");//子进程命令
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
bSuccess = 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 an error occurs, exit the application.
if ( ! bSuccess )
ErrorExit(TEXT("CreateProcess"));
else
{
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
}
// Format a readable error message, display a message box,
// and exit from the application.
void ErrorExit(PTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
sprintf((LPTSTR)lpDisplayBuf,
"%s failed with error %d: %s",
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(1);
}
#include <stdio.h>
#include <string.h>
int main()
{
char in[128] = {0};
char out[128] ={"处理后的字符串为:"};
gets(in);
strcat(out,in);
puts(out);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
char in[128] = {0};
char out[128] ={"处理后的字符串为:"};
int StrLen = strlen(out);
for(;;)
{
gets(in);
strcat(out,in);
puts(out);
out[StrLen] = 0;
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main()
{
char in[128] = {0};
char out[128] ={"处理后的字符串为:"};
int StrLen = strlen(out);
for(;;)
{
gets(in);
strcat(out,in);
puts(out);
out[StrLen] = 0;
}
return 0;
}