Accessing Windows Known Folders in C# with SHGetKnownFolderPath
Windows has a list of well-known folders such as Documents
, Pictures
, Music
, etc. You can access most of these folders using the Environment.GetFolderPath
method in C#. Here's an example:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
However, this list is limited to the folders defined in the Environment.SpecialFolder
enumeration. If you need to access other well-known folders, such as Desktop
or Downloads
, you'll need to do it manually. You can use the SHGetKnownFolderPath
method from the Windows API to retrieve the path of these folders and a list of known folders can be found in the Windows SDK (C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um\KnownFolders.h
). Of course, you can use Microsoft.Windows.CsWin32
to generate the C# bindings for these APIs.
var desktopFolder = new Guid(0xB2C5E279, 0x7ADD, 0x439F, 0xB2, 0x8C, 0xC4, 0x1F, 0xE1, 0xBB, 0xF6, 0x72);
var result = PInvoke.SHGetKnownFolderPath(desktopFolder, Windows.Win32.UI.Shell.KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, hToken: null, out var path)
if (result.Succeeded)
{
var expandedValue = Environment.ExpandEnvironmentVariables(path.ToString());
Marshal.FreeCoTaskMem((nint)path.Value);
return FromPath(expandedValue);
}
Marshal.FreeCoTaskMem((nint)path.Value);
throw new Win32Exception(result.Value, $"Failed to get shell folder path for {knownFolder}");
If you don't want to do it manually, you can use the Meziantou.Framework.FullPath
NuGet package:
using Meziantou.Framework.FullPath;
var desktopPath = FullPath.GetKnownFolderPath(KnownFolder.Downloads);
Do you have a question or a suggestion about this post? Contact me!