WinAPI方法SHGetKnownFolderPath
是檢索特殊文件夾路徑的唯一正確方法 - 包括個人文件夾和Downloads文件夾。
還有其他方法可以獲得類似的結果,這些結果看起來很有前途,但最終只會在特定系統上出現完全錯誤的路徑(例如,合併或硬編碼路徑的部分或濫用舊的註冊表項)。其原因在於my CodeProject article,其中還列出了完整的解決方案。它提供了一個包裝類,支持檢索所有已知的94個特殊文件夾,以及更多的好東西。
對於這裏一個簡單的例子,我剛纔粘貼的解決方案的縮短版,能夠僅取出個人專用文件夾,例如下載:
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Class containing methods to retrieve specific file system paths.
/// </summary>
public static class KnownFolders
{
private static string[] _knownFolderGuids = new string[]
{
"{56784854-C6CB-462B-8169-88E350ACB882}", // Contacts
"{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}", // Desktop
"{FDD39AD0-238F-46AF-ADB4-6C85480369C7}", // Documents
"{374DE290-123F-4565-9164-39C4925E467B}", // Downloads
"{1777F761-68AD-4D8A-87BD-30B759FA33DD}", // Favorites
"{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}", // Links
"{4BD8D571-6D19-48D3-BE97-422220080E43}", // Music
"{33E28130-4E1E-4676-835A-98395C3BC3BB}", // Pictures
"{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}", // SavedGames
"{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}", // SavedSearches
"{18989B1D-99B5-455B-841C-AB7C74E4DDFC}", // Videos
};
/// <summary>
/// Gets the current path to the specified known folder as currently configured. This does
/// not require the folder to be existent.
/// </summary>
/// <param name="knownFolder">The known folder which current path will be returned.</param>
/// <returns>The default path of the known folder.</returns>
/// <exception cref="System.Runtime.InteropServices.ExternalException">Thrown if the path
/// could not be retrieved.</exception>
public static string GetPath(KnownFolder knownFolder)
{
return GetPath(knownFolder, false);
}
/// <summary>
/// Gets the current path to the specified known folder as currently configured. This does
/// not require the folder to be existent.
/// </summary>
/// <param name="knownFolder">The known folder which current path will be returned.</param>
/// <param name="defaultUser">Specifies if the paths of the default user (user profile
/// template) will be used. This requires administrative rights.</param>
/// <returns>The default path of the known folder.</returns>
/// <exception cref="System.Runtime.InteropServices.ExternalException">Thrown if the path
/// could not be retrieved.</exception>
public static string GetPath(KnownFolder knownFolder, bool defaultUser)
{
return GetPath(knownFolder, KnownFolderFlags.DontVerify, defaultUser);
}
private static string GetPath(KnownFolder knownFolder, KnownFolderFlags flags,
bool defaultUser)
{
IntPtr outPath;
int result = SHGetKnownFolderPath(new Guid(_knownFolderGuids[(int)knownFolder]),
(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);
}
}
[DllImport("Shell32.dll")]
private static extern int SHGetKnownFolderPath(
[MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, IntPtr hToken,
out IntPtr ppszPath);
[Flags]
private enum KnownFolderFlags : uint
{
SimpleIDList = 0x00000100,
NotParentRelative = 0x00000200,
DefaultPath = 0x00000400,
Init = 0x00000800,
NoAlias = 0x00001000,
DontUnexpand = 0x00002000,
DontVerify = 0x00004000,
Create = 0x00008000,
NoAppcontainerRedirection = 0x00010000,
AliasOnly = 0x80000000
}
}
/// <summary>
/// Standard folders registered with the system. These folders are installed with Windows Vista
/// and later operating systems, and a computer will have only folders appropriate to it
/// installed.
/// </summary>
public enum KnownFolder
{
Contacts,
Desktop,
Documents,
Downloads,
Favorites,
Links,
Music,
Pictures,
SavedGames,
SavedSearches,
Videos
}
(完全註釋版本在CodeProject上發現上面鏈接的文章。)
雖然這只是一個令人討厭的代碼牆,但你必須處理的表面非常簡單。以下是一個控制檯程序輸出Downloads文件夾路徑的示例。
private static void Main()
{
string downloadsPath = KnownFolders.GetPath(KnownFolder.Downloads);
Console.WriteLine("Downloads folder path: " + downloadsPath);
Console.ReadLine();
}
例如,只需撥打KnownFolders.GetPath()
您要查詢哪些路徑的文件夾的KnownFolder
枚舉值。
NuGet包
如果你不想經歷這一切hazzle,只需安裝我最近創建了我的NuGet包。這裏是project site,這裏是gallery link(請注意,使用情況是不同的和拋光,請參閱項目網站上的使用部分以獲取更多信息)。
也許使用'Environment.SpecialFolder' ** **枚舉?你試過嗎?path = Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.Personal)); path = Path.Combine(path,「Downloads」);'? – Kiquenet