1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmWin32ProcessExecution.h,v $
6 Date: $Date: 2002-10-05 14:24:45 $
7 Version: $Revision: 1.6 $
9 Copyright (c) 2002 Insight Consortium. All rights reserved.
10 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #ifndef cmWin32ProcessExecution_h
18 #define cmWin32ProcessExecution_h
21 * Portable 'popen' replacement for Win32.
23 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
24 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
25 * Return code handling by David Bolen <db3l@fitlinxx.com>.
29 * For more information, please check Microsoft Knowledge Base
30 * Articles Q190351 and Q150956.
33 #include "cmStandardIncludes.h"
38 /** \class cmWin32ProcessExecution
39 * \brief A process executor for windows
41 * cmWin32ProcessExecution is a class that provides a "clean" way of
42 * executing processes on Windows.
44 class cmWin32ProcessExecution
47 cmWin32ProcessExecution()
49 this->SetConsoleSpawn("w9xpopen.exe");
54 * Initialize the process execution datastructure. Do not call while
55 * running the process.
59 this->m_ProcessHandle
= 0;
60 this->m_ExitValue
= -1;
61 // Comment this out. Maybe we will need it in the future.
62 // file IO access to the process might be cool.
72 * Start the process in the directory path. Make sure that the
73 * executable is either in the path or specify the full path. The
74 * argument verbose specifies wether or not to display output while
75 * it is being generated.
77 bool StartProcess(const char*, const char* path
, bool verbose
);
80 * Wait for the process to finish. If timeout is specified, it will
81 * break the process after timeout expires. (Timeout code is not yet
84 bool Wait(int timeout
);
87 * Get the output of the process (mixed stdout and stderr) as
90 const std::string
GetOutput() const { return this->m_Output
; }
93 * Get the return value of the process. If the process is still
94 * running, the return value is -1.
96 int GetExitValue() const { return this->m_ExitValue
; }
99 * On Windows 9x there is a bug in the process execution code which
100 * may result in blocking. That is why this workaround is
101 * used. Specify the console spawn, which should run the
102 * Windows9xHack code.
104 void SetConsoleSpawn(const char* prog
) { this->m_ConsoleSpawn
= prog
; }
105 static int Windows9xHack(const char* command
);
107 /** Code from a Borland web site with the following explaination :
108 * In this article, I will explain how to spawn a console
109 * application and redirect its standard input/output using
110 * anonymous pipes. An anonymous pipe is a pipe that goes only in
111 * one direction (read pipe, write pipe, etc.). Maybe you are
112 * asking, "why would I ever need to do this sort of thing?" One
113 * example would be a Windows telnet server, where you spawn a shell
114 * and listen on a port and send and receive data between the shell
115 * and the socket client. (Windows does not really have a built-in
116 * remote shell). First, we should talk about pipes. A pipe in
117 * Windows is simply a method of communication, often between
118 * process. The SDK defines a pipe as "a communication conduit with
119 * two ends; a process with a handle to one end can communicate with
120 * a process having a handle to the other end." In our case, we are
121 * using "anonymous" pipes, one-way pipes that "transfer data
122 * between a parent process and a child process or between two child
123 * processes of the same parent process." It's easiest to imagine a
124 * pipe as its namesake. An actual pipe running between processes
125 * that can carry data. We are using anonymous pipes because the
126 * console app we are spawning is a child process. We use the
127 * CreatePipe function which will create an anonymous pipe and
128 * return a read handle and a write handle. We will create two
129 * pipes, on for stdin and one for stdout. We will then monitor the
130 * read end of the stdout pipe to check for display on our child
131 * process. Every time there is something availabe for reading, we
132 * will display it in our app. Consequently, we check for input in
133 * our app and send it off to the write end of the stdin pipe.
135 static bool BorlandRunCommand(const char* command
, const char* dir
,
136 std::string
& output
, int& retVal
, bool verbose
,
140 bool PrivateOpen(const char*, const char*, int, int);
141 bool PrivateClose(int timeout
);
143 HANDLE m_ProcessHandle
;
145 // Comment this out. Maybe we will need it in the future.
146 // file IO access to the process might be cool.
157 std::string m_Output
;
158 std::string m_ConsoleSpawn
;