Skip to content

Commit db794c5

Browse files
committed
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.
1 parent d820873 commit db794c5

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

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

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -217,31 +217,40 @@ 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.
224224
case SpecialFolder.System:
225-
// This assumes the system directory always exists and thus we don't need to do anything special for any SpecialFolderOption.
226-
return SystemDirectory;
225+
if (!string.IsNullOrEmpty(SystemDirectory))
226+
return SystemDirectory;
227+
228+
string? windir = Environment.GetEnvironmentVariable("windir");
229+
if (string.IsNullOrEmpty(windir))
230+
return string.Empty;
231+
232+
return Path.Combine(windir, "system32");
227233
default:
228234
return string.Empty;
229235

230-
// Map the SpecialFolder to the appropriate Guid
231236
case SpecialFolder.ApplicationData:
232237
folderGuid = Interop.Shell32.KnownFolders.RoamingAppData;
238+
fallbackEnv = "APPDATA";
233239
break;
234240
case SpecialFolder.CommonApplicationData:
235241
folderGuid = Interop.Shell32.KnownFolders.ProgramData;
242+
fallbackEnv = "ProgramData";
236243
break;
237244
case SpecialFolder.LocalApplicationData:
238245
folderGuid = Interop.Shell32.KnownFolders.LocalAppData;
246+
fallbackEnv = "LOCALAPPDATA";
239247
break;
240248
case SpecialFolder.Cookies:
241249
folderGuid = Interop.Shell32.KnownFolders.Cookies;
242250
break;
243251
case SpecialFolder.Desktop:
244252
folderGuid = Interop.Shell32.KnownFolders.Desktop;
253+
fallbackEnv = "PUBLIC";
245254
break;
246255
case SpecialFolder.Favorites:
247256
folderGuid = Interop.Shell32.KnownFolders.Favorites;
@@ -292,9 +301,11 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
292301
break;
293302
case SpecialFolder.ProgramFiles:
294303
folderGuid = Interop.Shell32.KnownFolders.ProgramFiles;
304+
fallbackEnv = "ProgramFiles";
295305
break;
296306
case SpecialFolder.CommonProgramFiles:
297307
folderGuid = Interop.Shell32.KnownFolders.ProgramFilesCommon;
308+
fallbackEnv = "CommonProgramFiles";
298309
break;
299310
case SpecialFolder.AdminTools:
300311
folderGuid = Interop.Shell32.KnownFolders.AdminTools;
@@ -346,12 +357,15 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
346357
break;
347358
case SpecialFolder.UserProfile:
348359
folderGuid = Interop.Shell32.KnownFolders.Profile;
360+
fallbackEnv = "USERPROFILE";
349361
break;
350362
case SpecialFolder.CommonProgramFilesX86:
351363
folderGuid = Interop.Shell32.KnownFolders.ProgramFilesCommonX86;
364+
fallbackEnv = "ProgramFiles(x86)";
352365
break;
353366
case SpecialFolder.ProgramFilesX86:
354367
folderGuid = Interop.Shell32.KnownFolders.ProgramFilesX86;
368+
fallbackEnv = "ProgramFiles(x86)";
355369
break;
356370
case SpecialFolder.Resources:
357371
folderGuid = Interop.Shell32.KnownFolders.ResourceDir;
@@ -364,18 +378,17 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
364378
break;
365379
case SpecialFolder.Windows:
366380
folderGuid = Interop.Shell32.KnownFolders.Windows;
381+
fallbackEnv = "windir";
367382
break;
368383
}
369384

370385
Guid folderId = new Guid(folderGuid);
371-
372386
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-
}
387+
if (hr == 0)
388+
return path;
377389

378-
return path;
390+
// Fallback logic if SHGetKnownFolderPath failed (nanoserver)
391+
return fallbackEnv != null ? Environment.GetEnvironmentVariable(fallbackEnv) ?? string.Empty : string.Empty;
379392
}
380393

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

0 commit comments

Comments
 (0)