dotnet / dotnet/runtime

[API Proposal]: Read an environment variable without expansion

Open
#132,366 5 comments 0 reactions 0 assignees View on GitHub
api-suggestion area-System.Runtime help wanted
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.