Created
December 8, 2017 23:12
-
-
Save smourier/c7771d4d5351c702f94118a0244856c8 to your computer and use it in GitHub Desktop.
Enum Shell Folders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void Interop() | |
{ | |
SHCreateItemFromParsingName("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", IntPtr.Zero, typeof(IShellItem).GUID, out IShellItem item); | |
item.BindToHandler(IntPtr.Zero, BHID_SFObject, typeof(IShellFolder).GUID, out IShellFolder folder); | |
folder.EnumObjects(IntPtr.Zero, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, out IEnumIDList list); | |
do | |
{ | |
list.Next(1, out IntPtr pidl, out int fetched); | |
if (fetched == 0) | |
break; | |
folder.GetDisplayNameOf(ILFindLastID(pidl), 0, out STRRET name); | |
Console.WriteLine(Marshal.PtrToStringUni(name.pOleStr)); | |
Marshal.FreeCoTaskMem(name.pOleStr); | |
Marshal.FreeCoTaskMem(pidl); | |
} | |
while (true); | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
private struct STRRET | |
{ | |
public int uType; | |
public IntPtr pOleStr; | |
} | |
private const int SHCONTF_FOLDERS = 0x00020; | |
private const int SHCONTF_NONFOLDERS = 0x00040; | |
private static readonly Guid BHID_SFObject = new Guid("3981e224-f559-11d3-8e3a-00c04f6837d5"); | |
[DllImport("shell32.dll", CharSet = CharSet.Unicode)] | |
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem); | |
[DllImport("shell32.dll")] | |
private static extern IntPtr ILFindLastID(IntPtr pidl); | |
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
private interface IShellItem | |
{ | |
void BindToHandler(IntPtr pbc, Guid bhid, Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv); | |
} | |
[Guid("000214e6-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
private interface IShellFolder | |
{ | |
void ParseDisplayName(); | |
[PreserveSig] | |
int EnumObjects(IntPtr hwnd, int grfFlags, [MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenumIDList); | |
void BindToObject(); | |
void BindToStorage(); | |
void CompareIDs(); | |
void CreateViewObject(); | |
void GetAttributesOf(); | |
void GetUIObjectOf(); | |
int GetDisplayNameOf(IntPtr pidl, int uFlags, out STRRET pName); | |
} | |
[Guid("000214f2-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
private interface IEnumIDList | |
{ | |
[PreserveSig] | |
int Next(int celt, out IntPtr rgelt, out int pceltFetched); | |
} |
Using IEnumShellItems:
var riid1 = typeof(IShellItem).GUID;
SHCreateItemFromParsingName("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", IntPtr.Zero, ref riid1, out IShellItem folder);
var BHID_EnumItems = new Guid("94f60519-2850-4924-aa5a-d15e84868039");
var riid2 = typeof(IEnumShellItems).GUID;
folder.BindToHandler(IntPtr.Zero, ref BHID_EnumItems, ref riid2, out IEnumShellItems items);
do {
items.Next(1, out IShellItem child, out uint fetched);
if (fetched == 0)
break;
child.GetDisplayName(SIGDN_NORMALDISPLAY, out string name);
child.GetDisplayName(SIGDN_FILESYSPATH, out string path);
Console.WriteLine($"{name} = {path}");
}
while (true);
private const int SIGDN_NORMALDISPLAY = 0x00000000;
private const int SIGDN_FILESYSPATH = unchecked((int)0x80058000);
[ComImport, Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellItem {
void BindToHandler(IntPtr pbc, ref Guid bhid, ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IEnumShellItems ppv);
void GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
int GetDisplayName([In] int sigdnName, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
}
[ComImport, Guid("70629033-E363-4A28-A567-0DB78006E6D7"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IEnumShellItems {
int Next(uint celt, out IShellItem rgelt, out uint pceltFetched);
int Skip([In] uint celt);
int Reset();
int Clone([MarshalAs(UnmanagedType.Interface)] out IEnumShellItems ppenum);
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
var riid1 = typeof(IShellItem).GUID;
SHCreateItemFromParsingName("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", IntPtr.Zero, ref riid1, out IShellItem item);
var BHID_SFObject = new Guid("3981e224-f559-11d3-8e3a-00c04f6837d5");
var riid2 = typeof(IShellFolder).GUID;
item.BindToHandler(IntPtr.Zero, ref BHID_SFObject, ref riid2, out IShellFolder folder);
folder.EnumObjects(IntPtr.Zero, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, out IEnumIDList list);
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
void BindToHandler(IntPtr pbc, ref Guid bhid, ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv);