Runtime: 'ProcessStartInfo.EnvironmentVariables聽["FOO"] = null' launches with empty environment variable

Created on 2 Apr 2020  路  4Comments  路  Source: dotnet/runtime

Repro:

class Program
{
    static void Main(string[] args)
    {
        var process = new System.Diagnostics.Process();
        process.StartInfo.FileName = "env";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.EnvironmentVariables ["FOO"] = null;
        process.Start();
        process.WaitForExit ();
    }
}

Execute:

$ dotnet run | grep FOO
FOO=

Try with mono:

csc *.cs /nologo && mono *.exe | grep FOO
[no output]

Allowing setting an environment variable to null to remove it would match the behavior of the Environment class, where you're supposed to Environment.SetEnvironmentVariable ("FOO", null); to delete that variable.

area-System.Diagnostics.Process

Most helpful comment

This is the result of:
https://github.com/dotnet/runtime/blob/a4a1c8beaf9b49bd3a76bbfc26432dbcabb32fd1/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs#L606

On Windows it is implemented as:
https://github.com/dotnet/runtime/blob/a4a1c8beaf9b49bd3a76bbfc26432dbcabb32fd1/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs#L904-L910

So on Windows, it has a similar behavior.

If you use EnvironmentVariables.Remove("FOO") you can get rid of the environment variable for the child.

Allowing setting an environment variable to null to remove it would match the behavior of the Environment class, where you're supposed to Environment.SetEnvironmentVariable ("FOO", null); to delete that variable.

The consistency would be nice. It would also be a breaking change.
Note that Environment doesn't have a separate method for Remove.

All 4 comments

/cc @stephentoub

This is the result of:
https://github.com/dotnet/runtime/blob/a4a1c8beaf9b49bd3a76bbfc26432dbcabb32fd1/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs#L606

On Windows it is implemented as:
https://github.com/dotnet/runtime/blob/a4a1c8beaf9b49bd3a76bbfc26432dbcabb32fd1/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs#L904-L910

So on Windows, it has a similar behavior.

If you use EnvironmentVariables.Remove("FOO") you can get rid of the environment variable for the child.

Allowing setting an environment variable to null to remove it would match the behavior of the Environment class, where you're supposed to Environment.SetEnvironmentVariable ("FOO", null); to delete that variable.

The consistency would be nice. It would also be a breaking change.
Note that Environment doesn't have a separate method for Remove.

It would also be a breaking change.

Would it really? If you in Windows execute set FOO= in a shell, FOO gets unset. I'm not aware of any instance where it would ever be requested, or even possible, to neither have nor spawn a child process with an environment variable with no value at all. In fact, even the documentation for SetEnvironmentVariable states about the value "If this parameter is NULL, the variable is deleted from the current process's environment."

To my understanding, that establishes it's in fact impossible, using the Win32 API, to have an environment variable without a value, and I'm willing to go out on a limb and guess the POSIX spec says the same thing.

If extending your quoted code to include the leading comment, we see even _there_ that a value is expected:

https://github.com/dotnet/runtime/blob/a4a1c8beaf9b49bd3a76bbfc26432dbcabb32fd1/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs#L902

So it seems that however we view it, from logic, from customer complaint, from Win32 and even from the documented _intention_ of the source code in question itself, and likely also from POSIX and any concievable shell on any platform, past, present or future, this is a bug.

It seems odd to oppose fixing such a bug, using unsubstantiated FUD as the only argument.

If the claim could be substantiated my position about fixing this bug would change, but I honestly don't think you can. I don't think anyone, anywehere, could be so... sick, as to depends on such a logic-defying behaviour, unless they were using it for malware.

@tamlin-mike both Windows and Linux can have environment variables which are set to an empty string.

It's important to identify breaking changes even when the suggested behavior is meaningful.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GitAntoinee picture GitAntoinee  路  3Comments

yahorsi picture yahorsi  路  3Comments

omariom picture omariom  路  3Comments

jzabroski picture jzabroski  路  3Comments

omajid picture omajid  路  3Comments