-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
REG_EXPAND_SZ environment variables not properly expanded for shells #9741
Comments
So, this isn’t the first issue with our environment block. Thanks for reporting it! We’re using the Win32 API that generates a new environment block and not doing anything special on top of that. It is rather alarming, but somewhat par for the course, that it doesn’t work quite right. We probably need to do more things manually instead of fewer things, because the API fixtures available to us do those things wrong. |
A system variable can't reliably refer to a user variable. This is going to be unreliable in many cases. It works with the shell APIs private First load system variables:
Next load user variables:
At each step it's only reliable to refer to variables that were loaded in a previous step. For example user These limitations have to be abided if you want the user's environment to be correct in contexts such as a process spawned with "runas.exe" or Task Scheduler, and various other cases that use I'd prefer a more reasonable and useful load order. It's always annoyed me that I can't reliably use |
When I originally set this up, the goal was to have a user-specific As this is a single-user machine, I can easily work around the problem by hardcoding the path, but I imagine there are other cases where people have done something similar without knowing it only worked because they'd only tried it in the large subset of cases where it didn't matter. I guess whether Windows Terminal 'fixes' this should depend on whether the goal is to make everything that used to work in CONHOST work or whether anyone doing anything sketchy should be forced to start doing it properly. |
I don't know the reason why they need a new environment block as opposed to creating a copy of the current environment that's returned by
Unfortunately, the order in which environment variables are loaded and expanded is not documented and not consistent in the system. Check that the value is set as expected with a fresh boot, and that it's not nonsense in system processes that inherit and extend the environment as the system boots (smss.exe, csrss.exe, wininit.exe, services.exe, winlogon.exe). Also, make sure that the desktop shell reloads the right value after setting a new value -- i.e. that it's compatible with
Or rather as close as one can get to 'prepended', reliably in practice. The default search paths for |
There's one Windows Terminal process that's the parent of all the tabs, so
It's survived at least a year of reboots without me noticing problems outside Windows Terminal, so it's at least consistent nonsense.
Yep, if I edit the value in Advanced System Settings and launch a fresh PowerShell, the variable gets expanded 'properly'.
I see the same behaviour as Windows Terminal, i.e.
Being Windows, it's more complicated than even that - things like the registry's list of known DLLs get involved before searching is even attempted. For what I needed, what I did was enough, though. Anyhow, while looking into this, I noticed that I've also got |
Users continually complain that shells spawned by Terminal do not reflect the most up-to-date system environment. We don't usually do work without reason 😉 |
I should have seen that this was the reason. If calling the undocumented function
Yes, both use I'd prefer a new
Since PowerShell modifes the value of
I didn't think about DLLs. It has been a while since I used |
The current behavior is definitely by design for when we regenerate a new environment block, but if other applications seem to handle this then I think we should take a crack at it. For reference, linking this up to #9233, #7418, #7204 for environment shenanigans. I suspect that we'll have to do something about them sooner rather than later. |
In #8933 (comment) and nearby comments, |
Does this explain why |
It's a |
The initial system "Path" value is a For a bad example, as mentioned above, the default value of That said, administrators and developers should still be made aware that dependent system environment variables cannot reliably depend on each other since they're expanded in arbitrary order. Similarly, dependent user environment variables cannot reliably depend on each other. This is a basic limitation of how the registry "Environment" keys are implemented. |
Windows Terminal version (or Windows build number)
1.7.572.0
Other Software
No response
Steps to reproduce
%USERPROFILE%
, e.g.TestVariable
set to%USERPROFILE%\bin
.REG_EXPAND_SZ
by finding it underHKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
.echo $env:TestVariable
.%USERPROFILE%
has been expanded, e.g.C:\Users\Chris\bin
is printed.echo $env:TestVariable
.%USERPROFILE%
has not been expanded, e.g.%USERPROFILE%\bin
is printed.Expected Behavior
Like with standalone PowerShell or CMD via CONHOST, the environment variable is properly expanded.
Actual Behavior
The unexpanded value is used.
This isn't happening with every environment variable - others get expanded correctly, like
windir
being%SystemRoot%
becomingC:\WINDOWS
. My suspicion is that it's just variables not defined in the system scope not being expanded if they're used in the system scope.I'm pretty sure this is Windows Terminal doing something weird rather than Windows itself as when viewing the
WindowsTerminal.exe
process' environment in Process Explorer, the variables are properly expanded, but when doing the same for the actual shell process, they aren't. If I had to guess, I'd say maybe Windows Terminal is attempting to read the up-to-date environment from the registry when starting new shells instead of letting them inherit its potentially outdated environment, but is doing so inconsistently with how Windows does it. If that's actually what's happening, it may be sensible to use Chocolatey's RefreshEnv batch script or PowerShell module as a reference implementation as that gets the same result as Windows.This is happening in MSYS-esque Bash shells, too, but the Windows-to-Unix path conversion seems to be doing another round of expansion that masks the symptoms.
The text was updated successfully, but these errors were encountered: