Skip to content

Commit cf0162f

Browse files
win32: add fallback to environment vars for system folder (#109673)
* win32: add fallback to environment vars for system folder Implement fallback to environment variables for system folders in NanoServer, ensuring correct paths when SHGetKnownFolderPath fails. * feedback * Update src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs --------- Co-authored-by: Tanner Gooding <[email protected]>
1 parent d4c7d86 commit cf0162f

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

src/libraries/Microsoft.Extensions.DependencyModel/tests/PackageResolverTest.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Collections.Generic;
66
using System.IO;
77
using FluentAssertions;
8-
using Microsoft.DotNet.XUnitExtensions;
98
using Microsoft.Extensions.DependencyModel.Resolution;
109
using Xunit;
1110
using F = Microsoft.Extensions.DependencyModel.Tests.TestLibraryFactory;
@@ -28,7 +27,7 @@ public void ShouldUseEnvironmentVariableToGetDefaultLocation()
2827
result.Should().Contain(PackagesPath);
2928
}
3029

31-
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))] // https://github.com/dotnet/runtime/issues/21430
30+
[Fact]
3231
public void ShouldUseNugetUnderUserProfile()
3332
{
3433
var environment = EnvironmentMockBuilder.Create()

src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
217217
// The only SpecialFolderOption defines we have are equivalent to KnownFolderFlags.
218218

219219
string folderGuid;
220-
220+
string? fallbackEnv = null;
221221
switch (folder)
222222
{
223223
// Special-cased values to not use SHGetFolderPath when we have a more direct option available.
@@ -230,12 +230,15 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
230230
// Map the SpecialFolder to the appropriate Guid
231231
case SpecialFolder.ApplicationData:
232232
folderGuid = Interop.Shell32.KnownFolders.RoamingAppData;
233+
fallbackEnv = "APPDATA";
233234
break;
234235
case SpecialFolder.CommonApplicationData:
235236
folderGuid = Interop.Shell32.KnownFolders.ProgramData;
237+
fallbackEnv = "ProgramData";
236238
break;
237239
case SpecialFolder.LocalApplicationData:
238240
folderGuid = Interop.Shell32.KnownFolders.LocalAppData;
241+
fallbackEnv = "LOCALAPPDATA";
239242
break;
240243
case SpecialFolder.Cookies:
241244
folderGuid = Interop.Shell32.KnownFolders.Cookies;
@@ -292,9 +295,11 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
292295
break;
293296
case SpecialFolder.ProgramFiles:
294297
folderGuid = Interop.Shell32.KnownFolders.ProgramFiles;
298+
fallbackEnv = "ProgramFiles";
295299
break;
296300
case SpecialFolder.CommonProgramFiles:
297301
folderGuid = Interop.Shell32.KnownFolders.ProgramFilesCommon;
302+
fallbackEnv = "CommonProgramFiles";
298303
break;
299304
case SpecialFolder.AdminTools:
300305
folderGuid = Interop.Shell32.KnownFolders.AdminTools;
@@ -346,12 +351,15 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
346351
break;
347352
case SpecialFolder.UserProfile:
348353
folderGuid = Interop.Shell32.KnownFolders.Profile;
354+
fallbackEnv = "USERPROFILE";
349355
break;
350356
case SpecialFolder.CommonProgramFilesX86:
351357
folderGuid = Interop.Shell32.KnownFolders.ProgramFilesCommonX86;
358+
fallbackEnv = "CommonProgramFiles(x86)";
352359
break;
353360
case SpecialFolder.ProgramFilesX86:
354361
folderGuid = Interop.Shell32.KnownFolders.ProgramFilesX86;
362+
fallbackEnv = "ProgramFiles(x86)";
355363
break;
356364
case SpecialFolder.Resources:
357365
folderGuid = Interop.Shell32.KnownFolders.ResourceDir;
@@ -364,18 +372,17 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
364372
break;
365373
case SpecialFolder.Windows:
366374
folderGuid = Interop.Shell32.KnownFolders.Windows;
375+
fallbackEnv = "windir";
367376
break;
368377
}
369378

370379
Guid folderId = new Guid(folderGuid);
371-
372380
int hr = Interop.Shell32.SHGetKnownFolderPath(folderId, (uint)option, IntPtr.Zero, out string path);
373-
if (hr != 0) // Not S_OK
374-
{
375-
return string.Empty;
376-
}
381+
if (hr == 0)
382+
return path;
377383

378-
return path;
384+
// Fallback logic if SHGetKnownFolderPath failed (nanoserver)
385+
return fallbackEnv != null ? Environment.GetEnvironmentVariable(fallbackEnv) ?? string.Empty : string.Empty;
379386
}
380387

381388
// Separate type so a .cctor is not created for Environment which then would be triggered during startup

0 commit comments

Comments
 (0)