Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Get Elements of a Known Folder with Windows API for w10

4.00/5 (5 votes)
23 May 2021CPOL 5.3K  
Get elements of known folder with the most recent API
I'm myself a beginner in Windows API, I spent a lot of time trying to understand how the new API worked, lost between a lot of old tutorials and answers using deprecated API. This is why after I resolved a part of my problem, I wanted to share it with the community.

Download

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 enums are available in the package source or on my github.

 

C#
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...");
       }

Screenshot

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)