[API Proposal]: Read an environment variable without expansion
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Description
i was instructed to post the issue here, as its about .NET api
main issue when SetEnvironmentVariable() is used that contains a %variable% the registry key is set as reg_sz instead of expanded
so the variable is not correctly save and breaking for example the path environment variable or other created variables
Proposed technical implementation details (optional)
GetEnvironmentVariable() add a new optional parameter that can be used to get a variable not expanded
This allows to save it to a variable and pass it directly to SetEnvironmentVariable without breaking %% inside variables
also for SetEnvironmentVariable it should detect if a % is inside the parameter and set the korrekt registrykey type when saving (reg_expand_sz) currently it always saves as reg_sz which breaks Path variable when used
here the current behaviour is described.
for the correct behaviour when creating the reg key (reg_sz or expanded), you can also look here at line 90
https://github.com/microsoft/PowerToys/blob/main/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesHelper.cs
currently this is how we can get env variables
GetEnvironmentVariable($Name, $Target)
we can expand this to be
GetEnvironmentVariable($Name, $Target, $DoNotExpand)
which toggles this behaviour
If the value passed to SetEnvironmentVariable($Name, $Value, $Target) contains "%" it should save as reg_expand_sz else reg_sz
this is already the implemented behaviour for EnvironmentVariable Editor inside PowerToys
and writing the registry directly because of this issue with SetEnvironmentVariable and unable to get Env variable unexpanded with GetEnvironmentVariable
some additional comments for info
https://github.com/PowerShell/PowerShell/issues/26725
### Reproduction Steps
use GetEnvironmentVariable($Name, $Target)
and SetEnvironmentVariable("Variable", [NullString]::Value)
### Expected behavior
set registry key correctly to expanded when % is used also add additional option to control get nonexpanded variable
additional optional parameter to get nonexpanded version of the variable
### Actual behavior
registry key in environment is always set as reg_SZ (nonExpandable) instead of expanded_sZ when key contains a %variable%
when getting environment variables, it always gets expanded so it is not possible to get and resave a variable as it will always break all user %variables%
### Regression?
no, its a long known issue but it can be fixed without breaking existing scripts or code
if desired i can give a more detailed script which showcases the exact behaviour that would need to be replicated in SetEnvironmentVariable() and GetEnvironmentVariable() to fix and improve it without breaking existing applications and code
### Known Workarounds
edit registry keys directly as .net SetEnvironmentVariable causes issues
### Configuration
latest .net, windows 11, x64
affects all known versions of windows and .net
### Other information
_No response_
Contributor guide
Research direction
Start by reviewing the current GetEnvironmentVariable and SetEnvironmentVariable APIs and the referenced EnvironmentVariablesHelper.cs line 90 in PowerToys, then reproduce the Windows registry behavior described in the issue. Done means environment values containing % are stored with the appropriate registry type and callers can retrieve unexpanded values without breaking existing usage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api, operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100