There is no way to copy a child environment into a parent one. However, you may use WshShell.Environment
object to create persistent environment variables in ways beyond setx
command capabilities.
Some time ago I wrote a Batch-JScript hybrid script called SetEnv.bat
:
@if (@CodeSection == @Batch) @then
:: SetEnv.bat: Creation of persistent environment variables via a JScript subroutine
:: Antonio Perez Ayala
@echo off
setlocal EnableDelayedExpansion
if "%~1" neq "" if "%~1" neq "/?" goto begin
set start=
for /F "delims=:" %%a in ('findstr /N "^</*usage>" "%~F0"') do (
if not defined start (set start=%%a) else set /A lines=%%a-start-1
)
set line=0
for /F "skip=%start% tokens=1* delims=:" %%a in ('findstr /N "^" "%~F0"') do (
echo(%%b
set /A line+=1
if !line! equ %lines% goto :EOF
)
<usage>
Create persistent environment variables.
SETENV charVar=code strVar:=string ... [/T:envtype]
charVar Specifies the name of one-character environment-variable.
code Ascii (Unicode) code of the character assigned to charVar;
any code is valid, excepting zero.
strVar Specifies the name of string environment-variable.
string String of characters assigned to strVar;
if contain spaces or special characters, enclose it in quotes.
/T Specify the environment type for the variables.
envtype SYSTEM Applies to all users of the computer and is saved
between logoffs and restarts in the registry.
USER Applies to the user currently logged on to the
computer and is saved between logoffs and restarts.
VOLATILE Applies to current logon session and is not saved
between logoffs and restarts (this is the default).
PROCESS Applies to current process and might be passed to
child processes.
Examples:
[call] SetEnv BEL=7 BS=8 TAB=9 CR=13 LF=10
[call] SetEnv LastLogoff:="%date% @ %time%" /T:USER
</usage>
:begin
rem Define the variables via JScript
Cscript /nologo /E:JScript "%~F0" %*
goto :EOF
@end
// JScript section: SetEnv subprogram
// Define environment variables given in command-line arguments with this format:
// charVar=code strVar:="string" ... [/T:SYSTEM|USER|VOLATILE|PROCESS]
// Antonio Perez Ayala
// Reference: http://technet.microsoft.com/en-us/library/ee156595.aspx
var envType = WScript.Arguments.Named.Item("T");
if ( envType == undefined ) envType = "VOLATILE";
var WshShell = WScript.CreateObject("WScript.Shell"),
colEnvVars = WshShell.Environment(envType),
args = WScript.Arguments.Unnamed, name_Value, equalSignPos;
for ( var i = 0; i < args.Length; i++ ) {
name_Value = args.Item(i);
equalSignPos = name_Value.indexOf("=");
if ( name_Value.charAt(equalSignPos-1) == ":" )
colEnvVars(name_Value.slice(0,equalSignPos-1)) = name_Value.slice(equalSignPos+1);
else {
colEnvVars(name_Value.slice(0,equalSignPos)) = String.fromCharCode(parseInt(name_Value.slice(equalSignPos+1)));
}
}
This way, you just need to modify your vcvarsall.bat
and replace the set varname=value
commands by the equivalent call SetEnv varname:="value"
ones; just pay attention to SetEnv syntax that require the colon-equal in string variables.
EDIT: New method as reply to the comment
@if (@CodeSection == @Batch) @then
@echo off
setlocal EnableDelayedExpansion
rem Get the list of current environment variables
set "v="
for /F "delims==" %%a in ('set') do set v[%%a]=def
rem Call vcvarsall.bat to create new variables
call "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat"
rem Create a file with just the newly created variables and values
(for /F "tokens=1* delims==" %%a in ('set') do (
set "v=%%a"
if "!v:~0,2!" neq "v[" if not defined v[%%a] echo %%a=%%b
)) > vcvars.txt
rem Call JScript code to define persistent variables
Cscript /nologo /E:JScript "%~F0" < vcvars.txt
del vcvars.txt
goto :EOF
@end
var WshShell = WScript.CreateObject("WScript.Shell"),
colEnvVars = WshShell.Environment("Volatile");
while ( ! WScript.Stdin.AtEndOfStream ) {
var line = WScript.Stdin.ReadLine();
var pos = line.indexOf("=");
colEnvVars(line.slice(0,pos)) = line.slice(pos+1);
}