12

Ok so I have an OpenFileDialog and I want to set the initial directory to the users 'Download' folder. This is an internal application and, therefore, I am sure that the user will be using Windows 7.

var ofd = new OpenFileDialog();

//This doesn't work
ofd.InitialDirectory =
    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Downloads");

//This doesn't work either
ofd.InitialDirectory = @"%USERPROFILE%\Downloads";

ofd.Filter = "Zip Files|*.zip";

ofd.ShowDialog();

txtFooBar.Text = ofd.FileName;

I have tried the above so far and neither work. No Exception is thrown, it just doesn't set the initial directory to the downloads folder.

Where am I going wrong?

Thanks

JMK
  • 27,273
  • 52
  • 163
  • 280
  • 2
    possible duplicate of [Downloads folder: not special enough?](http://stackoverflow.com/questions/3795023/downloads-folder-not-special-enough) – Hans Passant Mar 18 '12 at 18:05
  • Apologies, this worked perfectly for me. Thankyou Hans. – JMK Mar 18 '12 at 18:27

6 Answers6

14

I was able to use the environment to call directly but I had to add ToString() to the end. It didn't work until I added it.

saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Tim Melton
  • 337
  • 3
  • 6
  • Instead of rejecting the edits to my comment, I will say that when I posted this originally in 2015, I was required by my compiler to us ToString() to get this function to work. in VS2019, it works just fine. That was my experience and that is why I posted that comment. – Tim Melton Aug 27 '19 at 20:53
  • This answer doesn't help because it deals with the "Desktop" folder, not the "Downloads" folder that the questions asks for – NineBerry Dec 31 '22 at 03:08
6

Maybe this could help: https://stackoverflow.com/a/1175250/333404

UPDATE:

Works for me: https://stackoverflow.com/a/3795159/333404

  private void Button_Click_1(object sender, RoutedEventArgs e) {
            var ofd = new OpenFileDialog();
            ofd.InitialDirectory = GetDownloadsPath();
            ofd.Filter = "Zip Files|*.zip";
            ofd.ShowDialog();
        }

        public static string GetDownloadsPath() {
            string path = null;
            if (Environment.OSVersion.Version.Major >= 6) {
                IntPtr pathPtr;
                int hr = SHGetKnownFolderPath(ref FolderDownloads, 0, IntPtr.Zero, out pathPtr);
                if (hr == 0) {
                    path = Marshal.PtrToStringUni(pathPtr);
                    Marshal.FreeCoTaskMem(pathPtr);
                    return path;
                }
            }
            path = Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
            path = Path.Combine(path, "Downloads");
            return path;
        }

        private static Guid FolderDownloads = new Guid("374DE290-123F-4565-9164-39C4925E467B");
        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        private static extern int SHGetKnownFolderPath(ref Guid id, int flags, IntPtr token, out IntPtr path);
Community
  • 1
  • 1
Robar
  • 1,929
  • 2
  • 30
  • 61
  • Hmm, other directory's work ok, for example, Environment.GetFolderPath(Environment.SpecialFolder.Personal) works fine, but when I try and go one step further, the Initial Directory just reverts to the root of my C drive. – JMK Mar 18 '12 at 17:57
1

The Downloads folder has a localized name and anyway is never a good idea to assume a specific relative location of a well known folder (even if it's well documented) because it may be changed by user settings too.

Unlucky the SpecialFolder enumeration doesn't contain every known folder so you have to use a little bit of interop, see MSDN. From that page we can find the full list of known folders, what you're looking for is FOLDERID_Downloads, because the SHGetKnownFolderPath function requires a GUID you have to declare somewhere that constant. Your code will be then something like this:

static class ShellHelpers
{
 public static string GetDownloadsFolder()
 {
  string path;
  int result = SHGetKnownFolderPath(FOLDERID_Downloads, 0, IntPtr.Zero, out path);
  if (result != NOERROR)
   Marshal.ThrowExceptionForHR(result); // You may fallback to another method or folder

  return path;
 }

 private static readonly Guid FOLDERID_Downloads = new Guid("374DE290-123F-4565-9164-39C4925E467B");
 private static readonly int NOERROR = 0;

 [DllImport("shell32.dll", CharSet=CharSet.Unicode)]
 private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out string pszPath);
}

Please note you can use the P/Invoke signature you prefer (someone uses a StringBuilder, someone else an IntPtr).

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
0

I used @tim's answer and it worked fine. Only I used it without the ToString() method and directly with the Path.Combine() method.

private OpenFileDialog openFileDialog;
openFileDialog.InitialDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");
Lukas Kock
  • 439
  • 1
  • 3
  • 9
-1

Environment.GetEnvironmentVariable("USERPROFILE") + @"" + "Downloads"

-2

try this

ofd.InitialDirectory = @"%USERPROFILE%\My Documents\Downloads";
PraveenVenu
  • 8,217
  • 4
  • 30
  • 39