1 /* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
2 The author disclaims copyright to this source code. */
10 // TODO: exe name might be unicode so to support everything cmd or args
11 // should be unicode or we can assume that cmd and args are utf8 and
12 // convert them to utf16 and call CreateProcessW
13 #define DONT_INHERIT_HANDLES FALSE
15 // Given name of the command to exececute 'cmd', and its arguments 'args'
16 // return WinProcess object that makes it easier to handle the process
17 // Returns NULL if failed to create the process. Caller can use GetLastError()
18 // for detailed error information.
19 WinProcess
* WinProcess::Create(const char* cmd
, char* args
)
22 HANDLE stdOut
= INVALID_HANDLE_VALUE
;
23 HANDLE stdErr
= INVALID_HANDLE_VALUE
;
24 STARTUPINFOA siStartupInfo
;
25 PROCESS_INFORMATION piProcessInfo
;
26 SECURITY_ATTRIBUTES sa
;
28 sa
.nLength
= sizeof(sa
);
29 sa
.lpSecurityDescriptor
= 0;
30 sa
.bInheritHandle
= 1;
32 memzero(&siStartupInfo
, sizeof(siStartupInfo
));
33 memzero(&piProcessInfo
, sizeof(piProcessInfo
));
34 siStartupInfo
.cb
= sizeof(siStartupInfo
);
36 char stdoutTempName
[MAX_PATH
] = {0};
37 char stderrTempName
[MAX_PATH
] = {0};
38 char *stdoutTempNameCopy
= NULL
;
39 char *stderrTempNameCopy
= NULL
;
41 char buf
[MAX_PATH
] = {0};
42 int len
= GetTempPathA(sizeof(buf
), buf
);
43 assert(len
< sizeof(buf
));
44 // create temporary files for capturing stdout and stderr or the command
45 res
= GetTempFileNameA(buf
, "stdout", 0, stdoutTempName
);
49 res
= GetTempFileNameA(buf
, "stderr", 0, stderrTempName
);
53 stdoutTempNameCopy
= str_dup(stdoutTempName
);
54 stderrTempNameCopy
= str_dup(stderrTempName
);
56 stdOut
= CreateFileA(stdoutTempNameCopy
,
57 GENERIC_READ
|GENERIC_WRITE
,
58 FILE_SHARE_WRITE
|FILE_SHARE_READ
,
60 FILE_ATTRIBUTE_NORMAL
, 0);
61 if (INVALID_HANDLE_VALUE
== stdOut
)
64 stdErr
= CreateFileA(stderrTempNameCopy
,
65 GENERIC_READ
|GENERIC_WRITE
,
66 FILE_SHARE_WRITE
|FILE_SHARE_READ
,
68 FILE_ATTRIBUTE_NORMAL
, 0);
69 if (INVALID_HANDLE_VALUE
== stdErr
)
72 siStartupInfo
.hStdOutput
= stdOut
;
73 siStartupInfo
.hStdError
= stdErr
;
75 BOOL ok
= CreateProcessA(cmd
, args
, NULL
, NULL
, DONT_INHERIT_HANDLES
,
76 CREATE_DEFAULT_ERROR_MODE
, NULL
/*env*/, NULL
/*curr dir*/,
77 &siStartupInfo
, &piProcessInfo
);
82 // TODO: pass stdoutTempNameCopy and stderrTempNameCopy so upon
83 // WinProcess destruction the files can be deleted and their memory freed
84 WinProcess
*wp
= new WinProcess(&piProcessInfo
);
88 if (INVALID_HANDLE_VALUE
!= stdOut
) {
92 if (INVALID_HANDLE_VALUE
!= stdErr
) {
96 if (stdoutTempName
[0]) {
97 // TODO: delete stdoutTempName
99 if (stderrTempName
[0]) {
100 // TODO: delete stderrTempName
102 free(stdoutTempNameCopy
);
103 free(stderrTempNameCopy
);
107 WinProcess::WinProcess(PROCESS_INFORMATION
*pi
)
109 memcpy(&m_processInfo
, pi
, sizeof(PROCESS_INFORMATION
));