c++windowsfilesystemsboost-process

Boost.Process fails to handle executable path containing spaces


The following code is built and run on Windows 10 with msvc:

#define _WIN32_WINNT 0x0A00
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#pragma comment(lib, "ntdll.lib")

#include <string>
#include <iostream>
#include <boost/process.hpp>

using namespace std::literals;
namespace bp2 = boost::process;
namespace as = boost::asio;

int main(int argc, const char** argv)
{
    try {
        if (argc == 2 && argv[1] == "--launcher"s) {
            as::io_context ioctx;
            bp2::process childProcess{ ioctx, "C:\\Path With Spaces\\bp2test.exe"s, {} };
            childProcess.wait();
        }
        else {
            for (int i = 0; i < argc; i++) {
                std::cout << argv[i] << std::endl;
            }
            std::cout << "Press enter to continue...";
            std::cin.get();
        }
        return 0;
    }
    catch (const std::exception& e) {
        std::cout << "STD-derived exception: " << e.what() << std::endl;
    }
    catch (...) {
        std::cout << "Unknown exception caught" << std::endl;
    }
    return -1;
}

The resulting bp2test.exe is copied to C:\Path With Spaces\ and run with the flag --launcher. It executes itself as expected, however the args received are mangled. Instead of the expected single arg (path to the executable), it receives multiple:

C:\Path With Spaces>bp2test --launcher
C:\Path
With
Spaces\bp2test.exe
Press enter to continue...

Using boost::filesystem::path instead of a string directly produces identical results. Pre-quoting the string like this: bp2::process childProcess{ ioctx, R"("C:\Path With Spaces\bp2test.exe")"s, {} }; results in the exception:

STD-derived exception: default_launcher: The filename, directory name, or volume label syntax is incorrect [system:123 at C:\Users\Chili\Desktop\cpp\bp2test\bp2test\vcpkg_installed\x64-windows-static\x64-windows-static\include\boost\process\v2\windows\default_launcher.hpp:327:7 in function 'struct boost::process::v2::basic_process __cdecl boost::process::v2::windows::default_launcher::operator ()<class boost::asio::any_io_executor,class std::initializer_list<class boost::basic_string_view<char,struct std::char_traits > >&,>(class boost::asio::any_io_executor,class boost::system::error_code &,const class boost::filesystem::path &,class std::initializer_list<class boost::basic_string_view<char,struct std::char_traits > > &)']

How to correctly deal with executable paths containing spaces in boost.process (V2) under Windows?

Edit: boost version is 1.88


Solution

  • This is fixed in Boost 1.89.

    See this issue and the related commit.