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

Refreshenv should expand variables recursively in case they're new (includes solution) #1417

Open
GrahamTheCoder opened this issue Oct 5, 2017 · 10 comments

Comments

@GrahamTheCoder
Copy link

GrahamTheCoder commented Oct 5, 2017

What You Are Seeing?

refreshenv AKA Update-SessionEnvironment does not refresh environment variables which reference an environmental variable which has changed e.g. If $env:Path has just had %NV_HOME% added (as happens after installing NVM) then running refreshenv won't actually make the path variable work

What is Expected?

To expand references to other variables recursively

How Did You Get This To Happen? (Steps to Reproduce)

I added chocolatey to my PowerShell profile using

$profileInstall = @'
# Chocolatey profile
$ChocolateyProfile = "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
if (Test-Path($ChocolateyProfile)) {
    Import-Module "$ChocolateyProfile"
}
'@

$profileFile = "$profile"
$chocoProfileSearch = '$ChocolateyProfile'

$profileInstall | Out-File $profileFile -Append

Then set up this test case:

[System.Environment]::SetEnvironmentVariable('somethingPreviouslyUndefined', 'successfully expanded', 'process')
[System.Environment]::SetEnvironmentVariable('firstReference', '%somethingPreviouslyUndefined%', 'process')
[System.Environment]::SetEnvironmentVariable('secondReference', '%firstReference%', 'process')
[System.Environment]::SetEnvironmentVariable('thirdReference', '%secondReference%', 'process')

I expect to be able to refresh the environment sufficiently such that I can use $env:thirdReference in the same session and it'll return successfully expanded

Output Logs

PS C:\Users\Graham> refreshenv --verbose --debug
Refreshing environment variables from the registry for powershell.exe. Please wait...
Finished
PS C:\Users\Graham> $env:thirdReference
%secondReference%
PS C:\Users\Graham>   $VerbosePreference = "continue"
PS C:\Users\Graham> Update-SessionEnvironment --verbose --debug
VERBOSE: Refreshing environment variables from the registry.
PS C:\Users\Graham> $env:thirdReference
%secondReference%

Solution

function ExpandEnvironmentVariablesRecursive($unexpanded) {
    $previous = ''
    $expanded = $unexpanded
	while($previous -ne $expanded) {
        $previous = $expanded		
        $expanded = [System.Environment]::ExpandEnvironmentVariables($previous)
	}
    return $expanded 
}

#Example usage
[System.Environment]::SetEnvironmentVariable('somethingPreviouslyUndefined', 'successfully expanded', 'process')
[System.Environment]::SetEnvironmentVariable('firstReference', '%somethingPreviouslyUndefined%', 'process')
[System.Environment]::SetEnvironmentVariable('secondReference', '%firstReference%', 'process')
[System.Environment]::SetEnvironmentVariable('thirdReference', '%secondReference%', 'process')

$env:thirdReference = ExpandEnvironmentVariablesRecursive('%thirdReference%')

Before you assign things like $env:path in Update-SessionEnvironment just call ExpandEnvironmentVariablesRecursive on the value first.

I've also added this as a stackoverflow answer

@ferventcoder
Copy link
Member

I think you may want to be sure you are running refreshenv for PowerShell amd not the batch script. Key indicator? Note that it said it was running refreshenv for cmd.exe

@ferventcoder
Copy link
Member

So maybe ensure the Chocolatey PowerShell profile is installed first and see if it already does the right thing?

@ferventcoder
Copy link
Member

The refreshenv.bat you saw it running in your output would never have any effect on PowerShell because it needs to start a subprocess to apply that batch, and those changes go away when that subprocess exits.

@GrahamTheCoder
Copy link
Author

Ah thanks, I think you're right that in my minimized test case I ended up calling the batch version accidentally. Because there's an alias set up I had assumed I was running that, but it probably wasn't imported.

I'll post the output with the the PowerShell cmdlet tomorrow

@ferventcoder
Copy link
Member

👍

@GrahamTheCoder
Copy link
Author

I've edited the original post (which used to incorrectly use refreshenv.bat) and replaced it with the powershell output so the comments before here won't make total sense any more

@GrahamTheCoder
Copy link
Author

This got stuck in triaging a long time ago. Is there anything I can do to move it forwards? Would it help if I make a PR that just adds this function and call it on these two lines:
https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/helpers/functions/Update-SessionEnvironment.ps1#L74
https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/helpers/functions/Update-SessionEnvironment.ps1#L81

@ma3yta
Copy link

ma3yta commented Apr 4, 2019

@ferventcoder please fix this bug
to reproduce:

choco install nvm -y
refreshenv
nvm on

@vbjay
Copy link

vbjay commented Jan 30, 2023

Ran a script using chocolatey to install nvm and then use nvm. Tried refreshenv in script. I am running the script in windows powershell. I know I have two workarounds.

  1. Start a new powershell instance with the script to do the build which include nvm install, nvm use calls.
  2. Use this reload environment variables process.

But it is crazy how long this issue has sat unfixed. We need a working refreshenv that actually reloads the environment as if we had just started powershell at the point of running refreshenv.

image

@ferventcoder

@vbjay
Copy link

vbjay commented Jan 31, 2023

Diagnostic for are you running the chocolatey version

Get-Command refreshenv

and in cmd

where refreshenv
choco upgrade nvm -y
nvm install lts

get-command refreshenv
refreshenv
nvm install lts

VirtualBox_CleanTest_30_01_2023_22_13_59

So this probably explains the problem. So the fix would be to make sure the chocolatey profile was imported correctly so that the alias runs and not refreshenv.cmd

I fixed typo and confirmed adding

$ChocolateyProfile = "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
if (Test-Path($ChocolateyProfile)) {
    Import-Module "$ChocolateyProfile"
}

solves the problem.

image

@pauby pauby mentioned this issue Mar 7, 2023
4 tasks
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

4 participants