Temporarily add the working directory to our path when starting an app

CreateProcess() doesn't search in the child's specified working directory by default.
This commit is contained in:
Cameron Gutman 2024-03-06 20:54:27 -06:00
parent 972e5d2b14
commit 06c0ed1d1c

View File

@ -933,6 +933,31 @@ namespace platf {
// Create a new console for interactive processes and use no console for non-interactive processes
creation_flags |= interactive ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW;
// Find the PATH variable in our environment block using a case-insensitive search
auto sunshine_wenv = boost::this_process::wenvironment();
std::wstring path_var_name { L"PATH" };
std::wstring old_path_val;
auto itr = std::find_if(sunshine_wenv.cbegin(), sunshine_wenv.cend(), [&](const auto &e) { return boost::iequals(e.get_name(), path_var_name); });
if (itr != sunshine_wenv.cend()) {
// Use the existing variable if it exists, since Boost treats these as case-sensitive.
path_var_name = itr->get_name();
old_path_val = sunshine_wenv[path_var_name].to_string();
}
// Temporarily prepend the specified working directory to PATH to ensure CreateProcess()
// will (preferentially) find binaries that reside in the working directory.
sunshine_wenv[path_var_name].assign(start_dir + L";" + old_path_val);
// Restore the old PATH value for our process when we're done here
auto restore_path = util::fail_guard([&]() {
if (old_path_val.empty()) {
sunshine_wenv[path_var_name].clear();
}
else {
sunshine_wenv[path_var_name].assign(old_path_val);
}
});
BOOL ret;
if (is_running_as_system()) {
// Duplicate the current user's token