Code change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: a case-sensitive list of environment variables and values, matching the output of from C# and .NET and the output of from PowerShell. It seems we should align the output to match the modern APIs for Windows that Microsoft provides. Instead, this happened: returns all environment variable names in all uppercase. Rust via : C# via : <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: </p</details
I don't think this is related to reading environment variables, but is related to process spawning. If you are spawning a process from a Rust program, then they will be uppercased. But if the Rust program is spawned from something else (like PowerShell), then the env keys should be case-preserved. The issue is . This was originally in to I personally don't think that issue is all that important that all environment keys should be forced to be uppercase. However, if there is a desire to fix both issues, then there would need to be a case-insensitive map (maybe just keep a separate set of uppercased keys?).
thanks for the pointer. For our case, Nushell should be able to spawn processes and keep the environment as expected rather than uppercasing. This allows Nushell to work just as PowerShell spawning a program. As best as I can tell, it's the lookup of a single variable that should be case-insensitive and that listing of variables should maintain the case they had, though I'm far from an expert here.
Hm, the current code does look wrong. Windows environment variables are compared case-insensitive but when set they keep the same case. The simplest improvement here would be remove the and instead implement , and in a way that ignores case differences. However, note that Windows uses Unicode casing, not just ASCII. There is for comparing but using it for would mean lots of conversions from OsString to the Windows string type (and back again). Calling Rust's Unicode functions with a WTF-8 OsString looks tricky too (though maybe there's something I'm missing). I'm uncertain how to approach a proper fix.

Related discussion:
text: ""u{03c0}u{042f}u{97f3}u{00e6}u{221e}"" ); } <ins> // On Windows, environment args are case preserving but comparisons are case-insensitive. // See: #85242 #[test] fn windows_env_unicode_case() { let test_cases = [ ("ä", "Ä"), ("ß", "SS"), ("Ä", "Ö"), ("Ä", "Ö"), ("I", "İ"), ("I", "i"), ("I", "ı"), ("i", "I"), ("i", "İ"), ("i", "ı"), ("İ", "I"), ("İ", "i"), ("İ", "ı"), ("ı", "I"), ("ı", "i"), ("ı", "İ"), ("ä", "Ä"), ("ß", "SS"), ("Ä", "Ö"), ("Ä", "Ö"), ("I", "İ"), ("I", "i"), ("I", "ı"), ("i", "I"), ("i", "İ"), ("i", "ı"), ("İ", "I"), ("İ", "i"), ("İ", "ı"), ("ı", "I"), ("ı", "i"), ("ı", "İ"), ]; // Test that `cmd.env` matches `env::set_var` when setting two strings that // may (or may not) be case-folded when compared. for (a, b) in test_cases.iter() { let mut cmd = Command::new("cmd"); cmd.env(a, "1"); cmd.env(b, "2"); env::set_var(a, "1"); env::set_var(b, "2"); for (key, value) in cmd.get_envs() { assert_eq!( env::var(key).ok(), value.map(|s| s.to_string_lossy().into_owned()), "command environment mismatch: {} {}", a, b ); } } } </ins>