1 #include "stdafx.h"
2 #include <windows.h>
3 #include <tchar.h>
4 #include <stdio.h>
5
6 HANDLE SpawnAndRedirect(LPCTSTR commandLine, HANDLE *hStdOutputReadPipe, LPCTSTR lpCurrentDirectory);
7
8 int _tmain()
9 {
10 HANDLE hOutput, hProcess;
11 hProcess = SpawnAndRedirect(_T("client.exe"), &hOutput, NULL);
12 if (!hProcess){
13 _tprintf(_T("Failed to spawn the thread\n"));
14 return 1;
15 }
16
17 char buffer[129];
18 DWORD read;
19 while(ReadFile(hOutput, buffer, 128, &read, NULL))
20 {
21 buffer[read] = '\0';
22 printf("%s\n", buffer);
23 }
24
25 CloseHandle(hOutput);
26 CloseHandle(hProcess);
27
28 return 0;
29 }
30
31
32 // The following function is a shortened variant of Q190351 - HOWTO: Spawn Console Processes with Redirected Standard Handles
33 // There is no special magic here, and this version doesn't address issues like:
34 // - redirecting Input handle
35 // - spawning 16-bits process
36 // - command-line limitations (unsafe 1024-char buffer)
37 // So you might want to use more advanced versions such as the ones you can find on CodeProject
38 HANDLE SpawnAndRedirect(LPCTSTR commandLine, HANDLE *hStdOutputReadPipe, LPCTSTR lpCurrentDirectory)
39 {
40 HANDLE hStdOutputWritePipe, hStdOutput, hStdError;
41 CreatePipe(hStdOutputReadPipe, &hStdOutputWritePipe, NULL, 0); // create a non-inheritable pipe
42 DuplicateHandle(GetCurrentProcess(), hStdOutputWritePipe,
43 GetCurrentProcess(), &hStdOutput, // duplicate the "write" end as inheritable stdout
44 0, TRUE, DUPLICATE_SAME_ACCESS);
45 DuplicateHandle(GetCurrentProcess(), hStdOutput,
46 GetCurrentProcess(), &hStdError, // duplicate stdout as inheritable stderr
47 0, TRUE, DUPLICATE_SAME_ACCESS);
48 CloseHandle(hStdOutputWritePipe); // no longer need the non-inheritable "write" end of the pipe
49
50 PROCESS_INFORMATION pi;
51 STARTUPINFO si;
52 ZeroMemory(&si, sizeof(STARTUPINFO));
53 si.cb = sizeof(STARTUPINFO);
54 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
55 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); // (this is bad on a GUI app)
56 si.hStdOutput = hStdOutput;
57 si.hStdError = hStdError;
58 si.wShowWindow = SW_HIDE; // IMPORTANT: hide subprocess console window
59 TCHAR commandLineCopy[1024]; // CreateProcess requires a modifiable buffer
60 _tcscpy(commandLineCopy, commandLine);
61 if (!CreateProcess( NULL, commandLineCopy, NULL, NULL, TRUE,
62 CREATE_NEW_CONSOLE, NULL, lpCurrentDirectory, &si, &pi))
63 {
64 CloseHandle(hStdOutput);
65 CloseHandle(hStdError);
66 CloseHandle(*hStdOutputReadPipe);
67 *hStdOutputReadPipe = INVALID_HANDLE_VALUE;
68 return NULL;
69 }
70
71 CloseHandle(pi.hThread);
72 CloseHandle(hStdOutput);
73 CloseHandle(hStdError);
74 return pi.hProcess;
75 }