Boost :: handle hidden console on windows

Recently released 1.64 release, including boost :: process. This provides a simple interface for starting processes. I used to use the standalone version of the boost :: process library (see here ). It worked well. I would like to upgrade to a newer version so that I can drop the standalone dependency.

The API is a little different, but everything works fine except for things. In the old version, I was able to pass in a Windows-specific context object that allowed me to hide any console windows opened by the process.

boost::process::win32_context ctx;
ctx.environment = boost::process::self::get_environment();

STARTUPINFOA stup;
ZeroMemory(&stup, sizeof(stup));
stup.cb = sizeof(stup);
stup.dwFlags = STARTF_USESHOWWINDOW;
stup.wShowWindow = SW_HIDE;
ctx.startupinfo = &stup;

std::vector<std::string> args;
boost::process:child process = boost::process::win32_launch("myprogram", args, ctx);

      

Using the new version looks like this:

boost::process::environment env = boost::this_process::environment();
boost::process:child process(boost::filesystem::path("myprogram"), env);

      

Everything works fine except for hiding the console window. Can this be achieved?

+3


source to share


1 answer


Constructor

child

accepts a list of types that will later be converted using fancy methods ::boost::fusion

in a chain of calls that do the actual initializations. This way, you can simply push the arguments of the supported type in any order:

#include <boost/process.hpp>
#include <boost/process/windows.hpp> // for windows::hide that can only be used on Windows

...

::boost::process::environment env = ::boost::this_process::environment();
::boost::process::child ch1("cmd", env, ::boost::process::windows::hide); // ok
::boost::process::child ch2(::boost::filesystem::path("C:\\Windows\\System32\\cmd.exe"), ::boost::process::windows::hide, env); // fine too

      



Hiding a window is conventionally not so easy, because windows::hide

both windows::show

are of different types and cannot be passed with the same function parameter. In this case, you need to write a special configuration handler:

struct show_window
:   ::boost::process::detail::handler_base
{
    private: ::boost::detail::winapi::WORD_ const m_flag;

    public: explicit
    show_window(bool const show) noexcept
    :   m_flag{show ? ::boost::detail::winapi::SW_SHOWNORMAL_ : ::boost::detail::winapi::SW_HIDE_}
    {}

    // this function will be invoked at child process constructor before spawning process
    template <class WindowsExecutor>
    void on_setup(WindowsExecutor &e) const
    {
        // we have a chance to adjust startup info
        e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESHOWWINDOW_;
        e.startup_info.wShowWindow |= m_flag;
    }
};

auto const need_to_show{false};
auto env{::boost::this_process::environment()};
::boost::process::child ch("cmd", env, show_window{need_to_show});

      

+3


source







All Articles