Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I determine the Windows 'Download folder' path?

Tags:

On my machine, it's here:

string downloadsPath = Path.Combine(    Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),    "Downloads"); 

But on a colleagues machine, this folder doesnt exist, and his Downloads folder is in his 'My Documents' folder. We are both on Windows 7*.

*Edit: in fact, it turns out he was not running the app on his own machine but a Windows Server 2003 machine.

like image 246
mackenir Avatar asked Oct 06 '11 10:10

mackenir


1 Answers

Windows does not define a CSIDL for the Downloads folder and it is not available through the Environment.SpecialFolder enumeration.

However, the new Vista Known Folder API does define it with the ID of FOLDERID_Downloads. Probably the easiest way to obtain the actual value is to P/invoke SHGetKnownFolderPath.

public static class KnownFolder {     public static readonly Guid Downloads = new Guid("374DE290-123F-4565-9164-39C4925E467B"); }  [DllImport("shell32.dll", CharSet=CharSet.Unicode)] static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out string pszPath);  static void Main(string[] args) {     string downloads;     SHGetKnownFolderPath(KnownFolder.Downloads, 0, IntPtr.Zero, out downloads);     Console.WriteLine(downloads); } 

Note that the P/invoke given on pinvoke.net is incorrect since it fails to use Unicode character set. Also I have taken advantage of the fact that this API returns memory allocated by the COM allocator. The default marshalling of the P/invoke above is to free the returned memory with CoTaskMemFree which is perfect for our needs.

Be careful that this is a Vista and up API and do not attempt to call it on XP/2003 or lower.

like image 140
David Heffernan Avatar answered Sep 19 '22 12:09

David Heffernan