
Wolfgang Fertsak wrote:
Hi, I ran into a problem when using the 2010 boost.process library within a Windows GUI application with WinMain() instead of main() without a console.
When I construct a context object the std[in|out|err]_behavior members are initialized in the constructor with calls to behavior::inherit::create(GetStdHandle(...)), which calls DuplicateHandle(). DuplicateHandle() fails with error 6 (invalid handle) since the application has no console and an exception is thrown.
So currently I don't see how I could use a context object from within a Windows GUI application since its constructor will always throw this exception.
What I want to do is start a child process and read its stdout as in the example "Communicating with child processes".
I've run into the same problem. It points out, IMHO, a major weakness in the design of the fundamental classes, which requires all context's to provide stream behaviors. To work around this issue I needed to create a null stream behavior, and a nullio_context. As in: namespace boost { namespace process { namespace behavior { class null : public stream { public: static boost::shared_ptr<null> create() { return boost::make_shared<null>(); } }; }}} namespace boost { namespace process { struct nullio_context { boost::shared_ptr<boost::process::behavior::stream> stdin_behavior; boost::shared_ptr<boost::process::behavior::stream> stdout_behavior; boost::shared_ptr<boost::process::behavior::stream> stderr_behavior; std::string process_name; std::string work_dir; boost::process::environment env; nullio_context() : stdin_behavior(boost::process::behavior::null::create()) , stdout_behavior(boost::process::behavior::null::create()) , stderr_behavior(boost::process::behavior::null::create()) , work_dir(boost::process::self::get_work_dir()) , env(boost::process::self::get_environment()) {} #if defined(BOOST_POSIX_API) void setup(std::vector<bool> &closeflags) { } #elif defined(BOOST_WINDOWS_API) void setup(STARTUPINFOA& ) { } #endif }; }} These are required because create_child reaches into context and asserts that there are instances of std in/out/err. It then directly accesses each of these I initially tried using the provided dummy behavior, which is a misnomer since it actually created temporary files and streams. I was an unhandled win32 exception when shutting down. The funny thing is there is already a context::setup method that would - at least on windows - allow the stream behavior to be fully encapsulated. A context could set the handle members of STARTUPINFOA only instantiating those boost::process::behavior::streams that are needed. On posix, setup could do all of the dup'ing of filenumbers, as it's called between fork and execve already. I've got a feeling there is a much better design lurking in the existing one, that would give a much more natural abstraction of the posix/windows requirements. Jeff