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:
- Is this an inherent limitation of Windows?
- Is there any way to circumvent this limitation using boost?
- Is there any way to circumvent this limitation using some other Win32 API function?
What I tired: using normal and UNC paths.