windows_CreateProcessCreatePipe_0">windows核心编程 内核对象,创建进程(CreateProcess),管道(CreatePipe)
windows核心编程 内核对象,创建进程(CreateProcess),管道(CreatePipe)
文章目录
- windows核心编程 内核对象,创建进程(CreateProcess),管道(CreatePipe)
- 主进程创建子进程并运行Ping 命令
主进程创建子进程并运行Ping 命令
/*
主进程创建子进程并运行Ping 命令
*/
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h> #define GRS_USEPRINTF() TCHAR pBuf[1024] = {}
#define GRS_PRINTF(...) \StringCchPrintf(pBuf,1024,__VA_ARGS__);\WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),pBuf,lstrlen(pBuf),NULL,NULL);#define GRS_USEPRINTFA() CHAR pBufA[1024] = {}
#define GRS_PRINTFA(...) \StringCchPrintfA(pBufA,1024,__VA_ARGS__);\WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),pBufA,lstrlenA(pBufA),NULL,NULL);#define GRS_ALLOC(sz) HeapAlloc(GetProcessHeap(),0,sz)
#define GRS_CALLOC(sz) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sz)
#define GRS_SAFEFREE(sz) if(NULL != p){HeapFree(GetProcessHeap(),0,p);p=NULL;} //获取应用程序所在的路径
void GetAppPath(PTSTR pszPath)
{DWORD dwLen = 0;//获取当前进程已加载模块的文件的完整路径dwLen = GetModuleFileName(NULL, pszPath, MAX_PATH);//NULL表示获取当前exe全路径if (dwLen == 0) return;for (DWORD i = dwLen; i > 0; i--){if ('\\' == pszPath[i]){pszPath[i + 1] = '\0';break;}}
}int _tmain()
{GRS_USEPRINTF();TCHAR pszAppPath[MAX_PATH + 1] = {};TCHAR pszExe[MAX_PATH + 1] = {};GetAppPath(pszAppPath);//获取当前exe文件所在的目录STARTUPINFO si = { sizeof(STARTUPINFO) };PROCESS_INFORMATION pi = {};SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES) };sa.bInheritHandle = FALSE;//该子进程不可继承printf("这是父进程的控制台窗口!\r\n");//重定向到管道,接受ping命令的输出GRS_USEPRINTFA();StringCchPrintf(pszExe, MAX_PATH, _T("PING www.baidu.com"));BYTE pBuffer[1024] = {};//缓存DWORD dwLen = 0;HANDLE hRead1, hWrite1;//管道读写句柄BOOL bRet;sa.bInheritHandle = TRUE;//创建匿名管道,管道句柄是可被继承的bRet = CreatePipe(&hRead1, &hWrite1, &sa, 1024);if (!bRet){GRS_PRINTF(_T("管道创建失败,Error Code:%d\n"), GetLastError());_tsystem(_T("PAUSE"));return 0;}/**/si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;si.wShowWindow = SW_HIDE;//隐藏子进程窗口si.hStdOutput = hWrite1;//将子进程的输出输入通道//创建子进程,ping命令,子进程是可继承的CreateProcess(NULL, pszExe, NULL, NULL, TRUE,DETACHED_PROCESS, NULL, pszAppPath, &si, &pi);//管道句柄已被继承,本地则可关闭,否则管道内核对象没有释放,// 之后的读管道操作人会一直等待管道吸入数据
// HANDLE pHandle = GetCurrentProcess();//0xfffffff
// HANDLE tHandle = GetCurrentThread();//0xfffffffe//党ping指向完毕,已经没有数据写入,就会因ReadFile读不到数据,而进程阻塞CloseHandle(hWrite1);printf("执行子进程:运行ping命令!\r\n");//读管道知道管道关闭dwLen = 1000;DWORD dwRead = 0;while (ReadFile(hRead1,pBuffer,dwLen,&dwRead,NULL)){if (0 == dwRead){break;}GRS_PRINTFA("%s\n", pBuffer);ZeroMemory(pBuffer, 1024);}GRS_PRINTF(_T("Read Completion!\n\n"));CloseHandle(hRead1);CloseHandle(pi.hProcess);CloseHandle(pi.hThread);_tsystem(_T("PAUSE"));return 0;
}