diff --git a/src/Avalonia.Base/Platform/Storage/FileIO/BclStorageProvider.cs b/src/Avalonia.Base/Platform/Storage/FileIO/BclStorageProvider.cs index fd2f499d06..d5434455b0 100644 --- a/src/Avalonia.Base/Platform/Storage/FileIO/BclStorageProvider.cs +++ b/src/Avalonia.Base/Platform/Storage/FileIO/BclStorageProvider.cs @@ -109,7 +109,7 @@ internal abstract class BclStorageProvider : IStorageProvider if (OperatingSystemEx.IsWindows()) { return Environment.OSVersion.Version.Major < 6 ? null : - Marshal.PtrToStringUni(SHGetKnownFolderPath(s_folderDownloads, 0, IntPtr.Zero)); + TryGetWindowsKnownFolder(s_folderDownloads); } if (OperatingSystemEx.IsLinux()) @@ -148,7 +148,31 @@ internal abstract class BclStorageProvider : IStorageProvider } } + private static unsafe string? TryGetWindowsKnownFolder(Guid guid) + { + nint path = IntPtr.Zero; + string? result = null; + + try + { + var hr = SHGetKnownFolderPath(guid, 0, 0, &path); + if (hr == 0) + { + result = Marshal.PtrToStringUni(path); + } + } + finally + { + if (path != IntPtr.Zero) + { + Marshal.FreeCoTaskMem(path); + } + } + + return result; + } + private static readonly Guid s_folderDownloads = new Guid("374DE290-123F-4565-9164-39C4925E467B"); [DllImport("shell32.dll")] - private static extern IntPtr SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid id, int flags, IntPtr token); + private static unsafe extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid id, int flags, nint token, nint* ppszPath); }