Problem with boost::process with long (>260) start_dir (windows)

182 Views Asked by At

I am on Windows 10, and want to use boost process to start a child. When the child's working directory is too long, I get an exception:

CreateProcess failed: The directory name is invalid.

I wrote a test program to debug this:

#include <boost/process.hpp>
#include <boost/process/async.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <iostream>
#include <iomanip>
#include <thread>
#include <string>
#include <filesystem>

namespace bp = boost::process;

void test(const std::filesystem::path& wdir)
{
  boost::asio::io_context io;
  bp::child child;
  try
  {
    std::filesystem::create_directories(wdir);
    std::cout << "exists " << std::filesystem::exists(wdir) << " len " << wdir.generic_wstring().size() << '\n';
    std::cout << "start proc\n";
    child = bp::child(
      "C:/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe",
      std::vector<std::string> { "ls" },
      io,
      boost::process::start_dir = LR"(\\?\)" + wdir.generic_wstring());
    std::this_thread::sleep_for(std::chrono::seconds{ 3 });
    child.wait();
  }
  catch (const std::exception& e)
  {
    std::cout << "EXCEPTION " << e.what() << "\n";
  }
  std::cout << "done\n";
}

int main()
{
  std::cout << "short path\n";
  test("D:/tmp/10378020400asdfasdfqw4retf");

  std::cout << "\nlong path\n";
  test("D:/tmp/10378020400826168668/unicode/qwe/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiertzertz/aaaqqqwwwiiiiertzertz/eertz/"
    "iiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiii"
    "iiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiii"
    "iiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
    "i/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqw"
    "wwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiii"
    "iiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiii"
    "iiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiii"
    "iiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/a"
    "aaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwi"
    "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiii"
    "iiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiii"
    "iiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiii"
    "iiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaq"
    "qqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiii"
    "iiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii/aaaqqqwwwiiiiiiiiiiiii"
    "iiiiiiiiiiiiiiiiiii/");
  return 0;
}

I get this output:

short path
exists 1 len 33
start proc
done

long path
exists 1 len 2177
start proc
EXCEPTION  CreateProcess failed: The directory name is invalid.
done

It seems the problem comes from the internally called CreateProcessW.

The documentation does not mention any limit for lpCurrentDirectory, and also allows UNC paths (hence I tried adding the prefix \\?\), but it does not make any difference whether I use the UNC syntax or not.

My questions are:

  1. Is this an inherent limitation of Windows?
  2. Is there any way to circumvent this limitation using boost?
  3. Is there any way to circumvent this limitation using some other Win32 API function?

What I tired: using normal and UNC paths.

0

There are 0 best solutions below