@@ -11,6 +11,7 @@ module;
1111#include < cstdio>
1212#include < cstdlib>
1313#if defined(_WIN32)
14+ #include < stdlib.h> // _putenv_s
1415#define popen _popen
1516#define pclose _pclose
1617#endif
@@ -424,22 +425,18 @@ std::filesystem::path sandbox_init_marker(const Env& env) {
424425std::string build_command_prefix (const Env& env) {
425426 auto xvmBin = paths::sandbox_bin (env).string ();
426427#if defined(_WIN32)
427- // Windows: use cmd.exe set + call semantics.
428- if (env.projectDir .empty ()) {
429- return std::format (
430- " cd /d {} && set \" PATH={};%PATH%\" && set \" XLINGS_HOME={}\" && set \" XLINGS_PROJECT_DIR=\" && {}" ,
431- shq (env.home .string ()),
432- xvmBin,
433- env.home .string (),
434- shq (env.binary .string ()));
428+ // Windows: set environment variables via the process environment
429+ // (cmd.exe `set` in compound &&-chains is unreliable) then invoke
430+ // xlings directly. _putenv_s is inherited by popen/system child.
431+ _putenv_s (" XLINGS_HOME" , env.home .string ().c_str ());
432+ _putenv_s (" XLINGS_PROJECT_DIR" ,
433+ env.projectDir .empty () ? " " : env.projectDir .string ().c_str ());
434+ // Prepend sandbox bin to PATH
435+ {
436+ std::string newPath = xvmBin + " ;" + (std::getenv (" PATH" ) ? std::getenv (" PATH" ) : " " );
437+ _putenv_s (" PATH" , newPath.c_str ());
435438 }
436- return std::format (
437- " cd /d {} && set \" PATH={};%PATH%\" && set \" XLINGS_HOME={}\" && set \" XLINGS_PROJECT_DIR={}\" && {}" ,
438- shq (env.home .string ()),
439- xvmBin,
440- env.home .string (),
441- env.projectDir .string (),
442- shq (env.binary .string ()));
439+ return shq (env.binary .string ());
443440#else
444441 if (env.projectDir .empty ()) {
445442 // Global mode: unset XLINGS_PROJECT_DIR (existing behavior).
@@ -663,10 +660,9 @@ int install_with_progress(const Env& env, std::string_view target,
663660 R"( {{"targets":["{}"],"yes":true}})" , target);
664661
665662#if defined(_WIN32)
666- auto cmd = std::format (
667- " cd /d {} && set \" XLINGS_PROJECT_DIR=\" && set \" XLINGS_HOME={}\" && {} interface install_packages --args {} 2>nul" ,
668- shq (env.home .string ()),
669- env.home .string (),
663+ _putenv_s (" XLINGS_HOME" , env.home .string ().c_str ());
664+ _putenv_s (" XLINGS_PROJECT_DIR" , " " );
665+ auto cmd = std::format (" {} interface install_packages --args {} 2>nul" ,
670666 shq (env.binary .string ()),
671667 shq (argsJson));
672668#else
@@ -787,13 +783,16 @@ void ensure_init(const Env& env, bool quiet) {
787783 auto marker = paths::sandbox_init_marker (env);
788784 if (std::filesystem::exists (marker)) return ;
789785
786+ // Ensure the home directory exists before cd'ing into it.
787+ std::error_code ec;
788+ std::filesystem::create_directories (env.home , ec);
789+
790790 if (!quiet)
791791 print_status (" Initialize" , " mcpp sandbox layout (one-time)" );
792792#if defined(_WIN32)
793- auto cmd = std::format (
794- " cd /d {} && set \" XLINGS_PROJECT_DIR=\" && set \" XLINGS_HOME={}\" && {} self init >nul 2>&1" ,
795- shq (env.home .string ()),
796- env.home .string (),
793+ _putenv_s (" XLINGS_HOME" , env.home .string ().c_str ());
794+ _putenv_s (" XLINGS_PROJECT_DIR" , " " );
795+ auto cmd = std::format (" {} self init >nul 2>&1" ,
797796 shq (env.binary .string ()));
798797#else
799798 auto cmd = std::format (
0 commit comments