Get Elements of a Known Folder with Windows API for w10
Get elements of known folder with the most recent API
Introduction
It shows subelements, directly from a known folder under Windows 10, with the most recent APIs. It's a very simple example for beginners. Written in C#, .NET Core 3.1. There is no UI, just console to not interfere.
Background
This tip have been written with research on pinvoke, internet, and I found most of the solution on the Raymon Chen's blog.
Using the Code
Here is the most part of the code, to understand easily how to deal with API windows. All the interfaces and enum
s are available in the package source or on my github.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start...");
HResult reslt = HResult.E_FAIL;
// On récupère l'élement
// Get element
IShellItem spsiFolder;
int res = ShellAPI.SHGetKnownFolderItem(
new Guid(KnownFolderID.ComputerFolder),
(uint)KnownFolderFlags.None,
IntPtr.Zero,
typeof(IShellItem).GUID,
out spsiFolder);
// Récupération du nom
// Get Name
IntPtr pName;
reslt = spsiFolder.GetDisplayName(SIGDN.NORMALDISPLAY, out pName);
if (reslt == HResult.S_OK)
{
// On affiche
// Show directly value
Console.WriteLine(Marshal.PtrToStringUni(pName));
// On libère
// Free it
Marshal.FreeCoTaskMem(pName);
}
// Get handle on sub elements
IntPtr pEnum;
reslt = spsiFolder.BindToHandler(IntPtr.Zero, new Guid(BHID.EnumItems),
typeof(IEnumShellItems).GUID, out pEnum);
if (reslt == HResult.S_OK)
{
IntPtr pszName = IntPtr.Zero;
IntPtr pszPath = IntPtr.Zero;
IEnumShellItems pEnumShellItems = null;
pEnumShellItems = Marshal.GetObjectForIUnknown(pEnum) as IEnumShellItems;
IShellItem psi = null;
uint nFetched = 0;
while (HResult.S_OK ==
pEnumShellItems.Next(1, out psi, out nFetched) && nFetched == 1)
{
pszName = pszPath = IntPtr.Zero;
// Pointeurs
reslt = psi.GetDisplayName(SIGDN.NORMALDISPLAY, out pszName);
reslt = psi.GetDisplayName(SIGDN.DESKTOPABSOLUTEEDITING, out pszPath);
if (reslt == HResult.S_OK)
{
// Récupérer les valeurs
// Retrieve values to a string
string sDisplayName = Marshal.PtrToStringUni(pszName);
string sDisplayPath = Marshal.PtrToStringUni(pszPath);
// Résultat
Console.WriteLine(string.Format("\tItem Name : {0}", sDisplayName));
Console.WriteLine(string.Format("\tItem Path : {0}", sDisplayPath));
// On libère
// Free it
Marshal.FreeCoTaskMem(pszName);
Marshal.FreeCoTaskMem(pszPath);
}
}
}
return;
Console.WriteLine("End...");
}
Points of Interest
It took me a long time to find all the information. I was not even sure each time if it was what I wanted to do. Then I would share to help others. Now, I understand how Windows APIs work.
History
- 22nd May, 2021: Initial version