Environment.SetEnvironmentVariable() messing up system variables and registry keys #58
Comments
Thanks for reporting the issue. The .NET framework is just using the underlying Windows Win32 API SetEnvironmentVariable which has this behavior and that is the behavior since this API is introduced. If you want to change the variable contents without changing the registry key type is to directly edit the registry contents. |
@tarekgh As far as I know (and I am using Win32 API since at least 1997), native SetEnvironmentVariable() function cannot change system or user environment variables in the registry, only the ones in the process (and its child processes) environment block. Environment.SetEnvironmentVariable() method on the other hand has an overload which by means of specifying If you could take a moment to check the Environment.SetEnvironmentVariable() implementation, you will hopefully notice that SetValue() wrapper method is passing The bug I reported is caused by A potential fix would be In my opinion it is already bad that |
@levicki thanks for clarification. You are right regarding the overload one is not using the Win32 APIs. Unfortunately, this is something we cannot change in the current time for the full framework because there will be some app comparability risk with such change. We can consider addressing this in .NET Core. You may move this issue to corefx repo or I can do that if you agree. |
@tarekgh Sorry if my report wasn't clear. Could you clarify what kind of compatibility risk you expect here? Do you think that some applications may be relying on broken behavior (i.e. expansion of variables)? How would not expanding them break anything if the registry key is properly marked as REG_EXPAND_SZ? Do you have any telemetry to back that up? Sure it's your code and you can decide not to fix it, or fix only .NET Core, but please be aware that people might already be using this method in their setup utilities and if those are 32-bit and run on 64-bit OS they will expand variables incorrectly due to WOW64 redirection thus breaking user systems' ability to run some applications which depend on valid PATH. Finally, I cannot say for sure whether NVIDIA driver and their CUDA toolkit setup are using .NET API or native Win32 API, but they already exhibit such behavior of incorrect PATH expansion. As a matter of fact I reported the bug to NVIDIA first (their internal bug #2532268), but then I realized that this .NET method is most likely what is enabling it. In my opinion, it should be fixed everywhere, but feel free to move it to .NET Core if you are still unconvinced. |
Someone can be dependent on the current be behavior. expecting the data will be expanded and possibly expecting REG_SZ registry type.
It is possible. We have seen some weird dependencies before on wrong behaviors.
Someone would just read the registry after setting the environment variable and expect it is expanded. This is possible.
This is cannot be used as argument for such case. Even there is no telemetry data not supporting that doesn't mean the case cannot happen. I am trying to say this is the .NET behavior for many years and changing that now can be risky especially there is a work around to just access the registry directly. I'll move the issue to .NET Core and thanks for your report. |
I don't mean to come off as argumentative, but how can that argument work when the OS default is
While it is possible it is a strawman. Why would they use
It is irrelevant whether it will happen or not. If developer wants expanded variables they should use
And what I hear you saying is "well yes, I wonder what is the point of having a framework in the first place if everyone who wants to use it has to possess higher level of system and WinAPI knowledge than Microsoft's own software engineers who wrote and/or are maintaining the framework, and to spend time and resources to implement correct behavior for all the broken functions they find in it? |
I meant the sequence of the operation and not depending on the default system. Someone after calling set environment expect it is expanded.
Again, you are assuming the apps always doing the right things which not always the case.
No, what I am saying, if the current behavior of the API is not working for you, then there is a work around.
This API exist for almost 20 years now and I didn't hear this complain before. Which means the majority of apps really didn't run into any problem or even cared about this issue. Also, I have opened .NET Core issue to track fixing this for the future releases. |
Issue Title
Environment.SetEnvironmentVariable() messing up system variables and registry keys
Version info
.NET Framework Early Access build 3745 (it applies to all .Net Framework versions until now)
Windows Version 10.0.17763.379
General
If you use
Environment.SetEnvironmentVariable()
to changePATH
environment variable it will lead to the expansion of its content (any%var%
contained inPATH
variable will get replaced with its content), and the registry keyHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path
type will be changed fromREG_EXPAND_SZ
toREG_SZ
.What is worse, if you are running a 32-bit application on a 64-bit OS, expansions for system variables such as
%CommonProgramFiles%
,%COMSPEC%
,%PROCESSOR_ARCHITECTURE%
, or%ProgramFiles%
, will be incorrect due to WOW64 redirection so if you had for example%ProgramFiles%\7-Zip
in yourPATH
that will be expanded toC:\Program Files (x86)\7-Zip
instead ofC:\Program Files\7-Zip
.Finally, given that
ComSpec
,PSModulePath
, andwindir
registry keys are also by defaultREG_EXPAND_SZ
, if this function is used to change any of them it will mess them up as well.Actual behavior:
Expected behavior
Early Access ID
N/A
The text was updated successfully, but these errors were encountered: