Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment variables set in bash aren't picked up by Windows processes run from bash #1363

Closed
saxonww opened this issue Nov 14, 2016 · 4 comments

Comments

@saxonww
Copy link

saxonww commented Nov 14, 2016

Please use the following bug reporting template to help produce actionable and reproducible issues. Please try to ensure that the reproduction is minimal so that the team can go through more bugs!

  • A brief description

Some Windows processes depend on the environment for their behavior. One is msbuild when trying to compile a Visual Studio solution; Microsoft.Common.CurrentVersion.targets tries to set some properties using $([System.IO.Path]::GetTempPath()), which resolves to the value of %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory, whichever is found first. TMP, TEMP, and USERPROFILE are not set in bash by default, and unfortunately setting them doesn't work.

  • Expected results

Consider the following MSBuild script:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         DefaultTargets="build">
        <Target Name="build">
                <Message Text="$([System.IO.Path]::GetTempPath())" />
        </Target>
</Project>

Output from msbuild 14.0 in cmd.exe looks like this:

C:\work\msbuild>echo %TMP%
C:\Users\saxonww\AppData\Local\Temp

C:\work\msbuild>"c:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" test.proj
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 11/14/2016 1:32:01 PM.
Project "C:\work\msbuild\test.proj" on node 1 (default targets).
build:
  C:\Users\saxonww\AppData\Local\Temp\
Done Building Project "C:\work\msbuild\test.proj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.27
  • Actual results (with terminal output if applicable)

Even though TMP, TEMP, and USERPROFILE are all set, the output is wrong:

saxonww@MACHINE:/mnt/c/work/msbuild$ alias msbuild
alias msbuild='/mnt/c/Program\ Files\ \(x86\)/MSBuild/14.0/Bin/MSBuild.exe'

saxonww@MACHINE:/mnt/c/work/msbuild$ echo $TMP
C:\Users\saxonww\AppData\Local\Temp

saxonww@MACHINE:/mnt/c/work/msbuild$ echo $TEMP
C:\Users\saxonww\AppData\Local\Temp

saxonww@MACHINE:/mnt/c/work/msbuild$ echo $USERPROFILE
C:\Users\saxonww

saxonww@MACHINE:/mnt/c/work/msbuild$ msbuild test.proj
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 11/14/2016 1:35:24 PM.
Project "C:\work\msbuild\test.proj" on node 1 (default targets).
build:
  C:\WINDOWS\
Done Building Project "C:\work\msbuild\test.proj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.26

If it matters, the above is run under tmux.

Edit: I'm seeing similar weirdness when running windows commands from bash to do windows things. For example, if I run "start ./Solution.sln" from cmd.exe it will open Solution.sln using the associated Visual Studio and everything is fine. If I set an alias for 'start' to 'cmd.exe /c start' in bash, and run the same command, Visual Studio opens but throws a bunch of errors and eventually crashes with a 'debug' or 'close program' dialog. It's not clear whether this is environment related or not, but it seems likely to me.

  • Your Windows build number

14965.rs_prerelease.161104-1700

  • Steps / All commands required to reproduce the error from a brand new installation

Install WSL, install VS2015, set up alias, etc. as shown.

  • Strace of the failing command

The strace is pretty straightforward. I can attach the entire thing if required, but in particular the environment variables show up w/ execve if I run 'strace -v -s 65535 ', e.g.:

"USERPROFILE=C:\Users\saxonww", "PWD=/mnt/c/work/msbuild", "HOME=/home/saxonww", "TMP=C:\Users\saxonww\AppData\Local\Temp",

  • Required packages and commands to install

See our contributing instructions for assistance.

@saxonww
Copy link
Author

saxonww commented Dec 15, 2016

For anyone hitting this, you can sort-of work around it with some wrapper batch files.

I have one setup.bat:

@echo off                                                                                                                                                      
REM This must be called with cmd /v

for /f "tokens=1,2*" %%i in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"') do (
        CALL :DOSETVAR %%i "%%k"
)

REM the below don't appear in the registry, run 'set' in cmd.exe and copy over as needed
set ALLUSERSPROFILE=C:\ProgramData                                                                                                                             set CommonProgramFiles=C:\Program Files\Common Files                                                                                                           set CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files                                                                                                set CommonProgramW6432=C:\Program Files\Common Files
set USERNAME=saxonww
set USERDOMAIN=INTERNAL
set USERDNSDOMAIN=INTERNAL.DOMAIN.LOCAL
set USERDOMAIN_ROAMINGPROFILE=INTERNAL
set USERPROFILE=C:\Users\saxonww
set APPDATA=C:\Users\saxonww\AppData\Roaming                                                                                                                 

for /f "tokens=1,2*" %%i in ('reg query "HKCU\Environment"') do (
        if "%%i"=="Path" (
                CALL :DOADDVAR %%i "%%k"
        )
        if not "%%i"=="Path" (
                CALL :DOSETVAR %%i "%%k"
        )
)
exit /b
                                                                                                                                                               :DOSETVAR
:DOSETVAR
set value=%2                                                                                                                                                   set value=%value:~1,-1%
set %1=!value!
set "value="
exit /b

:DOADDVAR
set value=%2
set value=%value:~1,-1%
set %1=!%1%!;!value!
set "value="
exit /b

And then, e.g. to run msbuild via msbuild.bat:

@echo off
call "C:\path\to\setup.bat"
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"

"C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild.exe" %*

Then set up an alias:

alias msbuild="cmd.exe /v /c c:/path/to/msbuild.bat"

I'm able to run start, nuget, and msbuild this way, which is so far what I really wanted.

@luser
Copy link

luser commented Sep 13, 2017

For the same reasons I described here arguing against automatic translation of commandline arguments, I'd argue against automatic translation of environment variables--it's going to be hard to get right in the general sense. I would like to have some way to set environment variables when spawning a Windows process, but making it explicitly opt-in sounds more sensible.

@jstarks
Copy link
Member

jstarks commented Dec 19, 2017

We added an opt-in mechanism for environment variable interop in insider build 17063. You set WSLENV to a list of environment variables that should be passed through.

@StefanScherer
Copy link

Another surprise of todays announcements 🎉
Very useful for my setup where I learned it the hard way of this gap. docker run -e ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants