Skip to content

Commit a884b78

Browse files
authored
Improved handling and falback for retrieving Downloads folder path on Windows
* Catch exceptions from 'SHGetKnownFolderPath' * Catch exceptions from 'Registry.GetValue' * Add COM object integration for Known Folder retrieval
1 parent 9cead7a commit a884b78

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

DownloadAssistant/Utilities/IOManager.cs

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,50 @@ public static bool TryGetFullPath(string path, out string result)
124124
/// <returns>The path to the downloads folder, or <c>null</c> if the path cannot be determined.</returns>
125125
/// <exception cref="ArgumentNullException">Thrown when the home path is null or an empty string on Unix platforms.</exception>
126126
/// <exception cref="ArgumentException">Thrown when the path to the downloads folder is not of the correct format.</exception>
127-
/// <exception cref="IOException">Thrown when an I/O error occurs.</exception>
128127
/// <exception cref="SecurityException">Thrown when the caller does not have the required permission to perform this operation.</exception>
129128
public static string? GetDownloadFolderPath()
130129
{
131130
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
132131
{
133-
string path = SHGetKnownFolderPath(new("374DE290-123F-4565-9164-39C4925E467B"), 0);
134-
if (string.IsNullOrEmpty(path))
135-
return Convert.ToString(
136-
Registry.GetValue(
137-
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
138-
, "{374DE290-123F-4565-9164-39C4925E467B}"
139-
, string.Empty));
140-
else return path;
132+
string? path = null;
133+
134+
try
135+
{
136+
path = SHGetKnownFolderPath(new("374DE290-123F-4565-9164-39C4925E467B"), 0);
137+
if (!string.IsNullOrEmpty(path))
138+
return path;
139+
}
140+
catch (Exception) { }
141+
142+
try
143+
{
144+
path = Convert.ToString(
145+
Registry.GetValue(
146+
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
147+
, "{374DE290-123F-4565-9164-39C4925E467B}"
148+
, string.Empty));
149+
}
150+
catch (Exception) { }
151+
152+
IKnownFolderManager? knownFolderManager = null;
153+
IKnownFolder? knownFolder = null;
154+
try
155+
{
156+
if (Type.GetTypeFromCLSID(new Guid("4DF0C730-DF9D-4AE3-9153-AA6B82E9795A")) is Type comClass && Activator.CreateInstance(comClass) is IKnownFolderManager manager)
157+
knownFolderManager = manager;
158+
knownFolderManager?.GetFolderByName("Downloads", out knownFolder);
159+
knownFolder?.GetPath(0, out path);
160+
if (!string.IsNullOrEmpty(path))
161+
return path;
162+
}
163+
catch (Exception) { }
164+
finally
165+
{
166+
if (knownFolder != null) Marshal.ReleaseComObject(knownFolder);
167+
if (knownFolderManager != null) Marshal.ReleaseComObject(knownFolderManager);
168+
}
169+
170+
return string.IsNullOrEmpty(path) ? null : path;
141171
}
142172
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
143173
{
@@ -155,6 +185,15 @@ private static extern string SHGetKnownFolderPath(
155185
[MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags,
156186
nint hToken = 0);
157187

188+
[ComImport]
189+
[Guid("8BE2D872-86AA-4D47-B776-32CCA40C7018")]
190+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
191+
private interface IKnownFolderManager { void GetFolderByName(string canonicalName, out IKnownFolder knownFolder); }
192+
193+
[ComImport]
194+
[Guid("3AA7AF7E-9B36-420C-A8E3-F77D4674A488")]
195+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
196+
private interface IKnownFolder { void GetPath(int flags, [MarshalAs(UnmanagedType.LPWStr)] out string path); }
158197

159198
/// <summary>
160199
/// Moves a file to a new location, overwriting the existing file if it exists.

0 commit comments

Comments
 (0)