18

W .Net możemy odzyskać ścieżki do "folderów specjalnych", takich jak Dokumenty/Pulpit itp. Dzisiaj próbowałem znaleźć sposób, aby uzyskać ścieżkę do folderu "Pobrane", ale wydaje się, że nie jest wystarczająco wyjątkowa.Jak programowo pobrać folder pobierania plików Windows "% USERPROFILE%/Downloads"?

Wiem, że mogę po prostu zrobić "C: \ Users \ Username \ Downloads", ale wydaje się to brzydkie rozwiązanie. Więc jak mogę odzyskać ścieżkę przy użyciu .Net?

Odpowiedz

0

Problem swoje Pierwsza odpowiedź brzmi: NIEPOPRAWNY wynik, jeśli domyślny katalog do pobrania został zmieniony na [Pobierz1]! Właściwym sposobem na to jest obejmujące wszystkie możliwości

using System; 
using System.Runtime.InteropServices; 

static class cGetEnvVars_WinExp { 
    [DllImport("Shell32.dll")] private static extern int SHGetKnownFolderPath(
     [MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, IntPtr hToken, 
     out IntPtr ppszPath); 

    [Flags] public enum KnownFolderFlags : uint { SimpleIDList = 0x00000100 
     , NotParentRelative = 0x00000200, DefaultPath = 0x00000400, Init = 0x00000800 
     , NoAlias = 0x00001000, DontUnexpand = 0x00002000, DontVerify = 0x00004000 
     , Create = 0x00008000,NoAppcontainerRedirection = 0x00010000, AliasOnly = 0x80000000 
    } 
    public static string GetPath(string RegStrName, KnownFolderFlags flags, bool defaultUser) { 
     IntPtr outPath; 
     int result = 
      SHGetKnownFolderPath (
       new Guid(RegStrName), (uint)flags, new IntPtr(defaultUser ? -1 : 0), out outPath 
      ); 
     if (result >= 0)   { 
      return Marshal.PtrToStringUni(outPath); 
     } else { 
      throw new ExternalException("Unable to retrieve the known folder path. It may not " 
       + "be available on this system.", result); 
     } 
    } 

} 

By to sprawdzić, jeśli specjalnie pragnienie osobistego pobierania dir, Ci domyślnie false flag ->

using System.IO; 
class Program { 
    [STAThread] 
    static void Main(string[] args)  { 
     string path2Downloads = string.Empty; 
     path2Downloads = 
      cGetEnvVars_WinExp.GetPath("{374DE290-123F-4565-9164-39C4925E467B}", cGetEnvVars_WinExp.KnownFolderFlags.DontVerify, false); 
     string[] files = { "" }; 
     if (Directory.Exists(path2Downloads)) { 
      files = Directory.GetFiles(path2Downloads); 
     } 
    }//Main 
} 

czy tylko jeden wiersz [ wykorzystujące Environment.ExpandEnvironmentVariables()] -> (najprostsze rozwiązanie)

using System.IO; 
class Program { 
    [STAThread] 
    static void Main(string[] args)  { 
     string path2Downloads = string.Empty; 
     string[] files = { "" }; 
     path2Downloads = Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\Downloads"); 
     if (Directory.Exists(path2Downloads)) { 
      files = Directory.GetFiles(path2Downloads); 
     } 
    }//Main 
} 
19

Tak, to jest wyjątkowe, odkrycie nazwy tego folderu stało się niemożliwe dopiero w systemie Vista. .NET wciąż musi obsługiwać wcześniejsze systemy operacyjne. Można pinvoke SHGetKnownFolderPath(), aby obejść to ograniczenie, tak:

using System.Runtime.InteropServices; 
... 

public static string GetDownloadsPath() { 
    if (Environment.OSVersion.Version.Major < 6) throw new NotSupportedException(); 
    IntPtr pathPtr = IntPtr.Zero; 
    try { 
     SHGetKnownFolderPath(ref FolderDownloads, 0, IntPtr.Zero, out pathPtr); 
     return Marshal.PtrToStringUni(pathPtr); 
    } 
    finally { 
     Marshal.FreeCoTaskMem(pathPtr); 
    } 
} 

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); 
+1

Czy istnieje sposób, aby to działało na zlokalizowanym systemie Windows przed Vista? To znaczy. 'Path.Combine (path," Downloads ");' nie zadziała, ponieważ folder nazywa się 'Téléchargements', a nie' Downloads'. –

+0

Prawdopodobnie możesz go gdzieś wykopać z rejestru. Nie wiem, gdzie dawno temu przeszedłem na emeryturę. Regedit.exe przydaje się, aby go odzyskać. –

+0

Dlaczego warto używać 'SHGetKnownFolderPath', a nie' Environment.SpecialFolder'? – Kiquenet

-3

Dla VB, spróbuj ...

Dim strNewPath As String = IO.Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)) + "\Downloads\" 
+1

To jest złe, s. moje uwagi tutaj: http://www.codeproject.com/Articles/878605/Getting-all-Special-Folders-in-NET –

+0

Nie twórz tutaj trudnych ścieżek kodu. Użytkownik mógł przenieść folder do innej lokalizacji (co jest dość łatwe w wersjach 8, 8.1 i 10) ... –

0

chciałbym spróbować:

Dim Dd As String = Environment.GetFolderPath(Environment.SpecialFolder.Favorites) 
Dim downloD As String = Dd.Replace("Favorites", "Downloads") 
txt1.text = downLoD 
+0

Zamieszczanie odpowiedzi na pytanie opublikowane i udzielone 6 lat temu - Proszę wyjaśnić, dlaczego rozwiązanie jest lepsze niż istniejący –

+0

*** Proszę wyjaśnić, dlaczego twoje rozwiązanie jest lepsze niż istniejące ***? Lepiej nie używać 'SHGetKnownFolderPath'? – Kiquenet

+2

** Nie bóg rozwiązanie: ** 'Użytkownik mógł przenieść folder do innej lokalizacji (co jest dość łatwe w 8, 8.1 i 10).' [Getting All "Specjalne foldery" w .NET] (https: // www.codeproject.com/articles/878605/getting-all-special-folders-in-net) – Kiquenet