Accessing Windows Known Folders in C# with SHGetKnownFolderPath

 
 
  • Gérald Barré

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:

C#
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.

C#
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:

C#
using Meziantou.Framework.FullPath;

var desktopPath = FullPath.GetKnownFolderPath(KnownFolder.Downloads);

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub