-
Notifications
You must be signed in to change notification settings - Fork 342
Chocolatey does not recapture PATHs modified by external installer #153
Comments
Command is a bit harder, but for powershell you suggested the following: Env:PATH = (@(,[Environment]::GetEnvironmentVariable('PATH', 'Machine') -s
plit ';') + @([Environment]::GetEnvironmentVariable('PATH', 'User') -split ';') | Select -Unique) -join ';' |
It's in issue #134 |
So I have a couple of questions
|
That PoshCode snippet is craziness... let me (manually) see if it actually works ;0 |
How do you do a full environment refresh? I would love for that to happen with both powershell and command... |
I can think of 2 ways to do this.. not sure on security implications.
|
Install-ChocolateyPath actually pushes the new path...perhaps we can emulate that a bit. |
But it won't carry all the way back to the command line. That's what I'm hoping that crazy poshcode will do. |
Ok -- just tried the PoshCode sample...
Original session does not have the new PATH So in short, no go. |
Boo... |
So if you want to get the keys #user
Get-Item HKCU:\Environment | Select -ExpandProperty Property
#machine
Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' | Select -ExpandProperty Property |
I think this might work. Assuming new_var is the environment variable set. Get-WmiObject Win32_Environment | where-object -filter {$_.Name -eq 'new_var'} | select VariableValue |
Yeah, except how do you know what new_var is if an MSI just ran and added some new stuff? ;0 |
Need both powershell and cmd shell versions... @mwrock we'd need to iterate over all of them. |
Yup. You would have to build a list before the install and then do a delta. |
For cmd -- fun! |
HA! We found the same article! |
I have used those reg tools before, but I cringe every time I see that old DOS batch style pattern matching stuff. I think the cmd guys had Larry Wall aspirations. |
I think the biggest issue then is the security considerations. As long as I can get to HKLM, the Powershell refresh is pretty straightforward. |
I also need to double check the rules for environment -- i.e. we know that PATH is special cased to munge Machine and User -- but not sure if any other variables are treated specially. I believe that User variables override Machine variables when the names overlap and there is no special casing like for PATH. Will try a few tests here to be sure. |
Verified - User overrides Machine. I gave PATHEXT a shot since it has a similar format to PATH. When I defined a User variant, it totally ate the Machine variant. So unless someone has a definitive resource somewhere about this -- I'm going to assume that only PATH has special treatment. |
say i wrote a helper chocolatey-restart that simply closes the active session and reopens a fresh posh. is this invasive? would it work? another random thought-maybe wmi event consumers can track the change to env vars... |
I played with some ideas today and I think I found a way to make this work for all env vars in ps and cmd with little batch ugliness. The gist of it is this. I'd have a Refresh-Environment.ps1 and RefreshEnvironment.bat. The ps1 would do something like:
What I foud is that you have to either use WMI or go directly to the registry and from a different process. Then it would use the xml api to build a PS dictionary of the environment variables that propperly resolves the system and user variables and does spacial handling on the path via concatenation. Finally it iterates the dictionary and flushes it to the env:\ drive. Then it outputs
to standard output. The bat calls the ps1 and flushes it to a file via >> and uses the
Based on some prototype tests, I think this works. I plan to extract this into a separate chocolatey/repo since I think it has usage scenarios outside of chocolatey. The snippits above might not be syntactically perfect but hopefully you get the idea. Hopefully I can get to this before the end of the weekend. Thoughts? |
I'm down for it if it works. :D |
I just cooked this up and it works just fine -- no separate process or WMI necessary (I tend to avoid WMI because its just a wrapper on top of other stuff -- with the ability to fail due to DCOM issues, etc) This is for Powershell only, not cmd. |
Very nice. Plugged that into my test simulator and it works. I think adding the batch compatibility should be straight forward by having this output the new vars to std out and then having a .bat call that and taking the FOR strategy I mentioned above. |
I'm just about done with a pull req.. just trying to get the unit tests to run under your test suite properly. Will kick it off just so you guys can have a look, but don't pull it quite yet ;0 |
Also note that I may have the wrong spot for integration into Chocolatey.. I'll let you guys sort that part out if it's in the wrong spot. |
Yeah I think this should probably go into Chocolatey-Nuget instead of Install-ChocolateyInstallPackage so it can be applied to all install scenarios. |
Roger that -- will fix. |
Pull updated with tests that work properly now... |
Great job! I'll add in the batch file version later unless someone else beats me too it. |
…md.exe This adds a command RefreshEnv.cmd to the bin files, so that one can update environment variables out of band. There is zero chance it will work once chocolatey.cmd calls exit /b %ERRORLEVEL% as exiting the batch effectively destroys any updates to local environmental changes. The way it currently works is effectively the same as using setlocal due to the use of exit. Since this command can be called out of band, it should be called out of band, whenever the user wants to refresh their environment variables they can call this. Note this only works in cmd.exe shell. There is no current way to update a powershell session other than importing the helper functions as a module and running Update-SessionEnvironment.
* stable: (chocolatey-archiveGH-460) Fix for "Package depending on newer chocolatey is installed using existing chocolatey" (chocolatey-archiveGH-459) Fix for "Cannot find Update-SessionInformation" (maint) formatting (chocolatey-archiveGH-153)(chocolatey-archiveGH-134) Update PATH on cmd.exe (maint) ensure powershell module loading preference is on
Neither cmd, nor Powershell will ever refresh their local copies of environment variables.
This is problematic for a couple of reasons
The problem here is that Powershell does not "recapture" the environment variables once a session has been started.
So PATH could be modified, after running an installer, but Chocolatey cannot gain access to these without using the .NET System EnvironmentVariable APIs or manually accessing the real location in the registry -- i.e..
IMHO, what needs to be done is that the environment needs to be refreshed after a given installer wraps up.
I think that it makes sense to do the recapture after an install runs.
https://github.com/chocolatey/chocolatey/blob/master/src/helpers/functions/Install-ChocolateyPackage.ps1#L63
To recapture any changes made to PATH by external processes.
The text was updated successfully, but these errors were encountered: