11

I have a batch file that calls a vbscript file. I am trying to have the vbscript file change an environment variable that is later used in the batch file that calls the vbscript file.

Here are snippetes from the files.

Parent.bat

Set Value="Initial Value"
cscript Child.vbs
ECHO Value = %VALUE%

Child.vbs

Set wshShell = CreateObject( "WScript.Shell" )
Set wshSystemEnv = wshShell.Environment( "Process" )
wshSystemEnv("VALUE") = "New Value"
Josh
  • 2,180
  • 3
  • 21
  • 24

5 Answers5

6

You can't. A process can pass environment variables to child processes, but not to its parent - and in this case the parent is cmd.exe, which is running your Parent.bat file.

There are of course other ways to communicate information back to the parent batch file - outputting to stdout or a file is an obvious way, e.g.

== Child.vbs ===
WScript.echo "New Value"

== Parent.cmd ===
for /f "tokens=*" %%i in ('cscript //nologo child.vbs') do set Value=%%i
echo %Value%
Joe
  • 114,633
  • 27
  • 187
  • 321
  • 1
    Just to add: The child cannot modify environment of parent, without parent allowing it using additional scripting on parent side. Imagine what nasty things can be made to happen if child could modify parent's environment. So short answer is child cannot modify parent's environment **in any process-subprocess scenario**. – anishsane Nov 17 '12 at 04:44
3

yes, you can.... however, you'll have to resetvars in your session. see the following link:

Is there a command to refresh environment variables from the command prompt in Windows?

'RESETVARS.vbs

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("System")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
path = oEnv("PATH")

set oEnv=oShell.Environment("User")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next

path = path & ";" & oEnv("PATH")
oFile.WriteLine("SET PATH=" & path)
oFile.Close

This is how I did it:

SET oShell = CREATEOBJECT("Wscript.Shell") 
dim varSet
SET varSet = NOTHING 

  SET varSet = oShell.Environment("SYSTEM") 
  varSet("WinVer") = "6.0.2008"

Then in a separate VB script (resetvars.vbs) I called from CMD script:

cscript //nologo \\%APPSERVER%\apps\IE9.0\restartvars.vbs   
call %TEMP%\resetvars.bat
Community
  • 1
  • 1
tgkone
  • 31
  • 1
0

Ho about this:

@echo off
set vbsFile=%temp%\createguid.vbs
call :CreateVbs
call :GetGuid NewGuid
echo.%NewGuid%
del %vbsFile%>nul
GOTO:EOF

:CreateVbs
echo.set obj = CreateObject("Scriptlet.TypeLib")>%vbsFile%  
echo.WScript.StdOut.WriteLine obj.GUID>>%vbsFile% 
GOTO:EOF

:GetGuid
for /f "tokens=*" %%i in ('cscript //nologo %vbsFile%') do set %1=%%i
GOTO:EOF

It is not pure batch script but works ok.

0
@echo off&color 4a&title %~n0&AT>NUL
IF %ERRORLEVEL% EQU 0 (
    goto 2
) ELSE (
    echo.
)
if not "%minimized%"=="" goto 1
set minimized=true & start /min cmd /C "%~dpnx0"&cls&exit
:1
wmic process where name="cmd.exe" CALL setpriority "realtime">nul&echo set shell=CreateObject("Shell.Application") > %~n0.vbs&echo shell.ShellExecute "%~dpnx0",,"%CD%", "runas", 1 >> %~n0.vbs&echo set shell=nothing >> %~n0.vbs&start %~n0.vbs /realtime&timeout 1 /NOBREAK>nul& del /Q %~n0.vbs&cls&exit
:2
echo %~dpnx0 admin mode look up&wmic process where name="cmd.exe" CALL setpriority "realtime"&timeout 3 /NOBREAK>nul
:3
echo x=msgbox("end of line" ,48, "%~n0") > %~n0.vbs&start %~n0.vbs /realtime&timeout 1 /NOBREAK>nul& del /Q %~n0.vbs&cls&exit
weird
  • 21
  • 1
0

I don't think you can do this. At least, you would need to mess with the environment block in the calling process, and there's no guarantee that it will respect this...

SamB
  • 8,218
  • 5
  • 44
  • 52