Added Windows.Shell.ShellIconExtractor as a threaded way to get all icons for a folder or list of items.

master
David Hall 2024-06-09 13:09:27 -06:00
parent fc4233f0d1
commit ac0a1ac301
5 changed files with 448 additions and 3 deletions

View File

@ -0,0 +1,253 @@
using Microsoft.Win32;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Vanara.Extensions;
using Vanara.InteropServices;
using Vanara.PInvoke;
using Vanara.PInvoke.Tests;
using static Vanara.PInvoke.Shell32;
using static Vanara.PInvoke.User32;
namespace Vanara.Windows.Shell.Tests;
[TestFixture]
public class ShellIconExtTests
{
[Test]
public void ExtTest()
{
ClearIconCache();
//using var psf = new ShellFolder(@"C:\Temp");
using var psf = new ShellFolder(KNOWNFOLDERID.FOLDERID_SkyDriveDocuments);
ShellIconExtractor extr = new(psf, bmpSize: 96);
var tw = TestContext.Out;
ManualResetEvent evt = new(false);
extr.IconExtracted += (s, e) => tw.WriteLine($"{e.ItemID} = {e.ImageListIndex}");
extr.Complete += (s, e) => { tw.WriteLine("Done"); evt.Set(); };
extr.Start();
Assert.That(evt.WaitOne(5000), Is.True);
}
private static void ClearIconCache() => Assert.That(SystemVolumeCache.CreateInitializedInstance().Purge(), ResultIs.Successful);
/*[Test]
public void CreateTest()
{
Ole32.CoInitialize();
new MyForm().ShowDialog();
Ole32.CoUninitialize();
}
public class MyForm : Form
{
const int icoSz = 64;
readonly Timer timer = new Timer { Interval = 5000 };
readonly ShellIconExtractor extr;
readonly ShellDataTable data;
private ListView lv;
private readonly System.Threading.CancellationTokenSource cTokSrc = new System.Threading.CancellationTokenSource();
private readonly List<(string, int)> misses = new List<(string, int)>();
public MyForm()
{
SIZE = new SIZE(700, 800);
StartPosition = FormStartPosition.CenterScreen;
TopMost = true;
FormClosing += (s, e) => cTokSrc.Cancel();
Load += MyForm_Load;
var fld = new ShellFolder(TestCaseSources.TempDir);
data = new ShellDataTable(fld);
extr = new ShellIconExtractor(fld) { ImageSize = icoSz };
Controls.Add(lv = new ListView() { Dock = DockStyle.Fill, LargeImageList = extr.ImageList, View = View.LargeIcon });
data.RowChanged += (s, e) => { if (e.Action == System.Data.DataRowAction.Add) lv.Invoke((MethodInvoker)(() => { lv.Items.Add(new ListViewItem(e.Row[0].ToString()) { Name = data.GetPIDL(e.Row).ToString(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING) }); })); };
extr.IconExtracted += (s, e) => lv.Invoke((MethodInvoker)(() =>
{
var str = e.ItemID.ToString(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING);
var lvi = lv.Items[str];
if (lvi != null)
{
lvi.ImageIndex = e.ImageListIndex;
lv.Refresh();
}
else
misses.Add((str, e.ImageListIndex));
}));
timer.Tick += (s, e) => { timer.Enabled = false; Close(); };
//timer.Enabled = true;
}
private async void MyForm_Load(object sender, EventArgs e)
{
await data.RefreshAsync(cTokSrc.Token);
//await System.Threading.Tasks.Task.Delay(500);
await extr.GetIconsAsync(cTokSrc.Token);
foreach (var i in misses)
lv.Items[i.Item1].ImageIndex = i.Item2;
misses.Clear();
lv.Refresh();
}
//protected override void OnPaint(PaintEventArgs e)
//{
// using var psf = new ShellFolder(TestCaseSources.TempDir);
// var isf = psf.IShellFolder;
// var pt = e.ClipRectangle.Location;
// var span = icoSz + padSz;
// foreach (var pidl in isf.EnumObjects(SHCONTF.SHCONTF_FOLDERS | SHCONTF.SHCONTF_NONFOLDERS | SHCONTF.SHCONTF_INCLUDEHIDDEN))
// {
// try
// {
// var lsz = icoSz;
// using var hlbmp = ShellIconExtractor.LoadThumbnail(isf, pidl, ref lsz);
// var ssz = icoSz2;
// using var hsbmp = ShellIconExtractor.LoadThumbnail(isf, pidl, ref ssz);
// if (hlbmp != null)
// {
// var bmp = hlbmp.ToBitmap();
// e.Graphics.DrawImage(bmp, new Rectangle(pt.X + padSz, pt.Y + padSz, bmp.Width, bmp.Height), new Rectangle(POINT.Empty, bmp.Size));
// }
// if (hsbmp != null)
// {
// var bmp = hsbmp.ToBitmap();
// e.Graphics.DrawImage(bmp, new Rectangle(pt.X + padSz * 2 + (int)icoSz, pt.Y + padSz, bmp.Width, bmp.Height), new Rectangle(POINT.Empty, bmp.Size));
// }
// }
// catch
// {
// }
// var x = pt.X + span;
// pt = x > (e.ClipRectangle.Right - span) ? new POINT(e.ClipRectangle.Left, pt.Y + (int)icoSz + (padSz * 2)) : new POINT(x, pt.Y);
// }
//}
}
[Test]
public void GetIconLocationTest()
{
//using var psf = ShellItem.Open("shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}") as ShellFolder;
using var psf = new ShellFolder(TestCaseSources.TempDir);
var isf = psf.IShellFolder;
var list = new List<long>();
foreach (var pidl in isf.EnumObjects(SHCONTF.SHCONTF_FOLDERS | SHCONTF.SHCONTF_NONFOLDERS | SHCONTF.SHCONTF_INCLUDEHIDDEN))
{
var watch = Stopwatch.StartNew();
var (hr, file, iIdx, wFlags) = GetIconLocation(isf, pidl);
watch.Stop();
list.Add(watch.ElapsedMilliseconds);
TestContext.WriteLine($"{watch.ElapsedMilliseconds,4} = {pidl}; {hr.ToString().TrimEnd('\r', '\n')}; {file},{iIdx}; {wFlags}");
}
}
[Test]
public void ExtractTest()
{
//using var psf = ShellItem.Open("shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}") as ShellFolder;
using var psf = new ShellFolder(TestCaseSources.TempDir);
var isf = psf.IShellFolder;
var list = new List<long>();
foreach (var pidl in isf.EnumObjects(SHCONTF.SHCONTF_FOLDERS | SHCONTF.SHCONTF_NONFOLDERS | SHCONTF.SHCONTF_INCLUDEHIDDEN))
{
var watch = Stopwatch.StartNew();
var loc = GetIconLocation(isf, pidl);
if (loc.hr.Failed) { watch.Stop(); continue; }
var hr = ExtractIcons(isf, pidl, loc.file, loc.iIdx, 32, 16, out var ilg, out var ism);
watch.Stop();
list.Add(watch.ElapsedMilliseconds);
TestContext.WriteLine($"{watch.ElapsedMilliseconds,4} = {pidl}; {hr.ToString().TrimEnd('\r', '\n')};");
ilg?.Dispose(); ism?.Dispose();
}
}
static (HRESULT hr, string file, int iIdx, GetIconLocationResultFlags wFlags) GetIconLocation(IShellFolder psf, PIDL pidl, GetIconLocationFlags flags = GetIconLocationFlags.GIL_FORSHELL)
{
var szIconFile = new StringBuilder(Kernel32.MAX_PATH);
HRESULT hr;
if (psf.GetUIObjectOf(HWND.NULL, 1, new[] { (IntPtr)pidl }, typeof(IExtractIconW).GUID, default, out var eiw).Succeeded)
{
try
{
hr = ((IExtractIconW)eiw).GetIconLocation(flags, szIconFile, szIconFile.Capacity, out var piTempIcon, out var wFlags);
return (hr, hr.Succeeded ? szIconFile.ToString() : null, piTempIcon, wFlags);
}
finally
{
Marshal.ReleaseComObject(eiw);
}
}
else if ((hr = psf.GetUIObjectOf(default, 1, new[] { (IntPtr)pidl }, typeof(IExtractIconA).GUID, default, out var ei)).Succeeded)
{
try
{
hr = ((IExtractIconA)ei).GetIconLocation(flags, szIconFile, szIconFile.Capacity, out var piTempIcon, out var wFlags);
return (hr, hr.Succeeded ? szIconFile.ToString() : null, piTempIcon, wFlags);
}
finally
{
Marshal.ReleaseComObject(ei);
}
}
return (hr, null, 0, 0);
}
static HRESULT ExtractIcons(IShellFolder psf, PIDL pidl, string szIconFile, int iIndex, ushort lg, ushort sm, out SafeHICON hIcoLg, out SafeHICON hIcoSm)
{
HRESULT hr;
//// Try IShellIcon first to get icon from system
//if (psf is IShellIcon shi)
//{
// hr = shi.GetIconOf(pidl, flags, out var iIndex);
// if (hr.Succeeded)
// {
// SHGetImageList((SHIL)iconSize, typeof(IImageList).GUID, out var il).ThrowIfFailed();
// return il.GetIcon(index, IMAGELISTDRAWFLAGS.ILD_TRANSPARENT);
// }
//}
// Try IExtractIcon(A&W) next to extract icons
if (psf.GetUIObjectOf(default, 1, new[] { (IntPtr)pidl }, typeof(IExtractIconW).GUID, default, out var eiw).Succeeded)
{
try
{
return ((IExtractIconW)eiw).Extract(szIconFile, (uint)iIndex, lg, out hIcoLg, sm, out hIcoSm);
}
finally
{
Marshal.ReleaseComObject(eiw);
}
}
else if ((hr = psf.GetUIObjectOf(default, 1, new[] { (IntPtr)pidl }, typeof(IExtractIconA).GUID, default, out var ei)).Succeeded)
{
try
{
return ((IExtractIconA)ei).Extract(szIconFile, (uint)iIndex, lg, out hIcoLg, sm, out hIcoSm);
}
finally
{
Marshal.ReleaseComObject(ei);
}
}
//// Try SHGetFileInfo last
//if (SHGetIDListFromObject(psf, out var fpidl).Succeeded)
//{
// var shfi = new SHFILEINFO();
// var ptr = SHGetFileInfo(PIDL.Combine(fpidl, pidl), 0, ref shfi, SHFILEINFO.Size, SHGFI.SHGFI_ICON | SHGFI.SHGFI_ADDOVERLAYS | SHGFI.SHGFI_PIDL);
//}
hIcoLg = hIcoSm = null;
return hr;
}
}*/
}

View File

@ -0,0 +1,191 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Vanara.PInvoke;
using static Vanara.PInvoke.Shell32;
using static Vanara.PInvoke.Shell32.ShellUtil;
namespace Vanara.Windows.Shell
{
/// <summary>Event arguments that expose an ID list and associated image.</summary>
/// <seealso cref="System.EventArgs"/>
public class ShellIconExtractedEventArgs(PIDL pidl, int idx) : EventArgs
{
/// <summary>Gets the retrieved icon.</summary>
/// <value>The icon.</value>
public int ImageListIndex { get; } = idx;
/// <summary>Gets the item ID list.</summary>
/// <value>The item ID list.</value>
public PIDL ItemID { get; } = pidl;
}
/// <summary>Class that simplifies extracting icons from items in a Shell Folder.</summary>
public class ShellIconExtractor
{
private const int defSize = 32;
private readonly List<Bitmap> images = [];
private readonly object imgLock = new(), lookLock = new();
private readonly FolderItemFilter itemFilter;
private readonly Dictionary<PIDL, int> lookup = [];
private readonly ShellFolder? parent = null;
private int imageSize = defSize;
private IEnumerable<PIDL>? items = null;
private CancellationTokenSource? lastCanceler;
private List<Task> lastRunThreads = [];
static ShellIconExtractor()
{
if (!FileIconInit(false)) FileIconInit(true);
}
/// <summary>Initializes a new instance of the <see cref="ShellIconExtractor"/> class to fetch icons for all items in a folder.</summary>
/// <param name="folder">The folder.</param>
/// <param name="filter">The filter to determine which child items of the folder are enumerated.</param>
/// <param name="bmpSize">The width and height of the bitmaps to fetch.</param>
public ShellIconExtractor(ShellFolder folder,
FolderItemFilter filter = FolderItemFilter.Folders | FolderItemFilter.NonFolders,
int bmpSize = defSize)
{
parent = folder;
itemFilter = filter;
imageSize = bmpSize;
}
/// <summary>Initializes a new instance of the <see cref="ShellIconExtractor"/> class.</summary>
/// <param name="items">The items.</param>
/// <param name="bmpSize">The width and height of the bitmaps to fetch.</param>
public ShellIconExtractor(IEnumerable<ShellItem> items, int bmpSize = defSize) :
this(items.Select(i => i.PIDL), bmpSize)
{ }
/// <summary>Initializes a new instance of the <see cref="ShellIconExtractor"/> class.</summary>
/// <param name="items">The items.</param>
/// <param name="bmpSize">The width and height of the bitmaps to fetch.</param>
public ShellIconExtractor(IEnumerable<PIDL> items, int bmpSize = defSize)
{
this.items = items.ToArray();
imageSize = bmpSize;
}
/// <summary>Occurs when all icons has been added to <see cref="ImageList"/>.</summary>
public event EventHandler? Complete;
/// <summary>Occurs when an updated icon has been added to <see cref="ImageList"/>.</summary>
public event EventHandler<ShellIconExtractedEventArgs>? IconExtracted;
/// <summary>Gets the list of all images.</summary>
/// <value>The list of all images.</value>
public IReadOnlyList<Bitmap> ImageList => images;
/// <summary>Gets or sets the width and height of the image.</summary>
/// <value>The size of the image.</value>
[DefaultValue(defSize)]
public int ImageSize
{
get => imageSize;
set
{
if (imageSize == value)
return;
imageSize = value;
Refresh();
}
}
/// <summary>Signals the process to end image retrieval.</summary>
public void Cancel() => lastCanceler?.Cancel();
/// <summary>Refreshes the list of images.</summary>
public void Refresh()
{
lastCanceler?.Cancel();
items ??= parent?.IShellFolder.EnumObjects((SHCONTF)itemFilter);
if (items is not null)
{
lock (lookLock) lookup.Clear();
lock (imgLock) images.Clear();
lastCanceler = new();
lastRunThreads = [];
HRESULT hr;
foreach (var i in items)
{
// Get IShellFolder for item
var info = new Info(parent?.IShellFolder, i, imageSize, lastCanceler.Token);
// Try to get the fast icon from IExtractIcon and then IExtractImage
if ((hr = LoadImageFromImageFactory(info.pidl, ref info.sz, SIIGBF.SIIGBF_INCACHEONLY, out var hbmp)).Succeeded && hbmp != null)
{
using (hbmp) AddBmp(hbmp.ToBitmap(), c => { lock (lookLock) lookup.Add(i, c); IconExtracted?.Invoke(this, new(i, c)); }); ;
}
else
{
// Spin up thread to get the real one
lastRunThreads.Add(Task.Factory.StartNew(GetImageThread, info, lastCanceler.Token));
}
}
Task.WhenAll(lastRunThreads).ContinueWith(t =>
{
if (!t.IsCanceled)
Complete?.Invoke(this, EventArgs.Empty);
}, lastCanceler.Token);
void AddBmp(Bitmap bmp, Action<int>? action = null) { lock (imgLock) images.Add(bmp); action?.Invoke(images.Count - 1); }
void GetImageThread(object? o)
{
var c = (Info)o!;
if (c.ct.IsCancellationRequested) return;
try
{
var hr = LoadImageFromImageFactory(c.pidl, ref c.sz, 0, out var hbmp);
if (hr.Failed || c.ct.IsCancellationRequested)
return;
AddBmp(hbmp!.ToBitmap(), cnt => { lock (lookLock) lookup[c.pidl] = cnt; IconExtracted?.Invoke(this, new(c.pidl, cnt)); });
}
finally
{
c.Dispose();
}
}
}
}
/// <summary>Starts this instance.</summary>
public void Start() => Refresh();
private class Info(IShellFolder? parent, PIDL pidl, int sz, CancellationToken ct) : IDisposable
{
#if DEBUG
public readonly string name = pidl.ToString(SIGDN.SIGDN_PARENTRELATIVE);
#endif
public readonly CancellationToken ct = ct;
public readonly PIDL pidl = pidl;
public SIZE sz = new(sz, sz);
private bool? isDir = null;
private IShellFolder? isf = parent;
public bool IsDir => isDir ?? (isDir = IsFolder()).Value;
public IShellFolder parent => isf ??= SHBindToParent<IShellFolder>(pidl)!;
public void Dispose() => isf = null;
private bool IsFolder()
{
if (isf is null)
{
SHFILEINFO sfi = new() { dwAttributes = (int)SFGAO.SFGAO_FOLDER };
return SHGetFileInfo(pidl, System.IO.FileAttributes.Directory, ref sfi, SHFILEINFO.Size, SHGFI.SHGFI_ATTRIBUTES | SHGFI.SHGFI_ATTR_SPECIFIED) != IntPtr.Zero && sfi.dwAttributes != 0;
}
return (SHGetDataFromIDList<WIN32_FIND_DATA>(isf, pidl, SHGetDataFormat.SHGDFIL_FINDDATA).dwFileAttributes & System.IO.FileAttributes.Directory) != 0;
}
}
}
}

View File

@ -11,7 +11,7 @@
<PackageReleaseNotes>Currently implements:
Classes
AddExtenderEventArgs, AppRegistration, AppSettingsFileListStorage, BindContext, ComClassFactory, CommandVerb, CommandVerbDictionary, ComObject, ComObjWrapper&lt;T&gt;, ControlPanel, DragEventArgs, ExtenderProviderBase&lt;T&gt;, FileInUseHandler, FileTypeAssociation, IconLocation, JumpList, JumpListDestination, JumpListItem, JumpListSeparator, JumpListTask, MemoryPropertyStore, MenuItemInfo, MessageEventArgs, MessageLoop, MRUManager, NativeClipboard, ProgId, PropertyBag, PropertyDescription, PropertyDescriptionList, PropertyStore, PropertyType, PropertyTypeList, ReadOnlyPropertyStore, RecycleBin, RegBasedDictionary&lt;T&gt;, RegBasedSettings, RegistryFileListStorage, SearchCondition, ShellAssociation, ShellAssociationHandler, ShellCommand, ShellContextMenu, ShellDataTable, ShellDropTarget, ShellExecuteCommand, ShellFileInfo, ShellFileNewOpEventArgs, ShellFileOperationDialog, ShellFileOperations, ShellFileOpEventArgs, ShellFolder, ShellFolderCategorizer, ShellFolderCategory, ShellImageList, ShellItem, ShellItemArray, ShellItemChangeEventArgs, ShellItemChangeWatcher, ShellItemImages, ShellItemPropertyStore, ShellItemPropertyUpdates, ShellLibrary, ShellLibraryFolders, ShellLink, ShellNavigationHistory, ShellRegistrar, ShellSearch, ShellSearchViewSettings, StockIcon, Taskbar, TaskbarList, TrayIcon, Utils, WallpaperManager, WallpaperMonitor, WallpaperSlideshow
AddExtenderEventArgs, AppRegistration, AppSettingsFileListStorage, BindContext, ComClassFactory, CommandVerb, CommandVerbDictionary, ComObject, ComObjWrapper&lt;T&gt;, ControlPanel, DragEventArgs, ExtenderProviderBase&lt;T&gt;, FileInUseHandler, FileTypeAssociation, IconLocation, JumpList, JumpListDestination, JumpListItem, JumpListSeparator, JumpListTask, MemoryPropertyStore, MenuItemInfo, MessageEventArgs, MessageLoop, MRUManager, NativeClipboard, ProgId, PropertyBag, PropertyDescription, PropertyDescriptionList, PropertyStore, PropertyType, PropertyTypeList, ReadOnlyPropertyStore, RecycleBin, RegBasedDictionary&lt;T&gt;, RegBasedSettings, RegistryFileListStorage, SearchCondition, ShellAssociation, ShellAssociationHandler, ShellCommand, ShellContextMenu, ShellDataTable, ShellDropTarget, ShellExecuteCommand, ShellFileInfo, ShellFileNewOpEventArgs, ShellFileOperationDialog, ShellFileOperations, ShellFileOpEventArgs, ShellFolder, ShellFolderCategorizer, ShellFolderCategory, ShellIconExtractedEventArgs, ShellIconExtractor, ShellImageList, ShellItem, ShellItemArray, ShellItemChangeEventArgs, ShellItemChangeWatcher, ShellItemImages, ShellItemPropertyStore, ShellItemPropertyUpdates, ShellLibrary, ShellLibraryFolders, ShellLink, ShellNavigationHistory, ShellRegistrar, ShellSearch, ShellSearchViewSettings, StockIcon, Taskbar, TaskbarList, TrayIcon, Utils, WallpaperManager, WallpaperMonitor, WallpaperSlideshow
Enumerations
ChangeFilters, DialogStatus, ExecutableType, FileUsageType, FolderItemFilter, LibraryFolderFilter, LibraryViewTemplate, LinkResolution, MenuPlacement, OperationFlags, OperationMode, OperationType, ShellIconType, ShellImageSize, ShellItemAttribute, ShellItemComparison, ShellItemDisplayString, ShellItemGetImageOptions, ShellItemToolTipOptions, TaskbarButtonProgressState, TransferFlags, VerbMultiSelectModel, VerbPosition, VerbSelectionModel, WallpaperFit

View File

@ -18,4 +18,4 @@ If you're still running into problems, file an [issue](https://github.com/dahall
Classes | Enumerations | Interfaces
--- | --- | ---
AddExtenderEventArgs AppRegistration AppSettingsFileListStorage BindContext ComClassFactory CommandVerb CommandVerbDictionary ComObject ComObjWrapper ControlPanel DragEventArgs ExtenderProviderBase FileInUseHandler FileTypeAssociation IconLocation JumpList JumpListDestination JumpListItem JumpListSeparator JumpListTask MemoryPropertyStore MenuItemInfo MessageEventArgs MessageLoop MRUManager NativeClipboard ProgId PropertyBag PropertyDescription PropertyDescriptionList PropertyStore PropertyType PropertyTypeList ReadOnlyPropertyStore RecycleBin RegBasedDictionary RegBasedSettings RegistryFileListStorage SearchCondition ShellAssociation ShellAssociationHandler ShellCommand ShellContextMenu ShellDataTable ShellDropTarget ShellExecuteCommand ShellFileInfo ShellFileNewOpEventArgs ShellFileOperationDialog ShellFileOperations ShellFileOpEventArgs ShellFolder ShellFolderCategorizer ShellFolderCategory ShellImageList ShellItem ShellItemArray ShellItemChangeEventArgs ShellItemChangeWatcher ShellItemImages ShellItemPropertyStore ShellItemPropertyUpdates ShellLibrary ShellLibraryFolders ShellLink ShellNavigationHistory ShellRegistrar ShellSearch ShellSearchViewSettings StockIcon Taskbar TaskbarList TrayIcon Utils WallpaperManager WallpaperMonitor WallpaperSlideshow | ChangeFilters DialogStatus ExecutableType FileUsageType FolderItemFilter LibraryFolderFilter LibraryViewTemplate LinkResolution MenuPlacement OperationFlags OperationMode OperationType ShellIconType ShellImageSize ShellItemAttribute ShellItemComparison ShellItemDisplayString ShellItemGetImageOptions ShellItemToolTipOptions TaskbarButtonProgressState TransferFlags VerbMultiSelectModel VerbPosition VerbSelectionModel WallpaperFit | IComObject IFileListStorage IJumpListItem IMenuBuilder
AddExtenderEventArgs AppRegistration AppSettingsFileListStorage BindContext ComClassFactory CommandVerb CommandVerbDictionary ComObject ComObjWrapper ControlPanel DragEventArgs ExtenderProviderBase FileInUseHandler FileTypeAssociation IconLocation JumpList JumpListDestination JumpListItem JumpListSeparator JumpListTask MemoryPropertyStore MenuItemInfo MessageEventArgs MessageLoop MRUManager NativeClipboard ProgId PropertyBag PropertyDescription PropertyDescriptionList PropertyStore PropertyType PropertyTypeList RecycleBin RegBasedDictionary RegBasedSettings RegistryFileListStorage SearchCondition ShellAssociation ShellAssociationHandler ShellCommand ShellContextMenu ShellDataTable ShellDropTarget ShellExecuteCommand ShellFileInfo ShellFileNewOpEventArgs ShellFileOperationDialog ShellFileOperations ShellFileOpEventArgs ShellFolder ShellFolderCategorizer ShellFolderCategory ShellIconExtractedEventArgs ShellIconExtractor ShellImageList ShellItem ShellItemArray ShellItemChangeEventArgs ShellItemChangeWatcher ShellItemImages ShellItemPropertyStore ShellItemPropertyUpdates ShellLibrary ShellLibraryFolders ShellLink ShellNavigationHistory ShellRegistrar ShellSearch ShellSearchViewSettings StockIcon Taskbar TaskbarList TrayIcon Utils WallpaperManager WallpaperMonitor WallpaperSlideshow | ChangeFilters DialogStatus ExecutableType FileUsageType FolderItemFilter LibraryFolderFilter LibraryViewTemplate LinkResolution MenuPlacement OperationFlags OperationMode OperationType ShellIconType ShellImageSize ShellItemAttribute ShellItemComparison ShellItemDisplayString ShellItemGetImageOptions ShellItemToolTipOptions TaskbarButtonProgressState TransferFlags VerbMultiSelectModel VerbPosition VerbSelectionModel WallpaperFit | IComObject IFileListStorage IJumpListItem IMenuBuilder

View File

@ -71,7 +71,6 @@ Class | Description
[Vanara.Windows.Shell.PropertyStore](https://github.com/dahall/Vanara/search?l=C%23&q=PropertyStore) | Encapsulates the IPropertyStore object.
[Vanara.Windows.Shell.PropertyType](https://github.com/dahall/Vanara/search?l=C%23&q=PropertyType) | Exposes methods that extract data from enumeration information.
[Vanara.Windows.Shell.PropertyTypeList](https://github.com/dahall/Vanara/search?l=C%23&q=PropertyTypeList) | Exposes methods that enumerate the possible values for a property.
[Vanara.Windows.Shell.ReadOnlyPropertyStore](https://github.com/dahall/Vanara/search?l=C%23&q=ReadOnlyPropertyStore) | Encapsulates the IPropertyStore object.
[Vanara.Windows.Shell.RecycleBin](https://github.com/dahall/Vanara/search?l=C%23&q=RecycleBin) | A static object that represents the system Recycle Bin.
[Vanara.Windows.Shell.RegBasedDictionary<T>](https://github.com/dahall/Vanara/search?l=C%23&q=RegBasedDictionary<T>) | A virtual dictionary that is based on values in the Windows Registry.
[Vanara.Windows.Shell.RegBasedSettings](https://github.com/dahall/Vanara/search?l=C%23&q=RegBasedSettings) | Base class for registry based settings.
@ -92,6 +91,8 @@ Class | Description
[Vanara.Windows.Shell.ShellFolder](https://github.com/dahall/Vanara/search?l=C%23&q=ShellFolder) | A folder or container of `Vanara.Windows.Shell.ShellItem` instances.
[Vanara.Windows.Shell.ShellFolderCategorizer](https://github.com/dahall/Vanara/search?l=C%23&q=ShellFolderCategorizer) | Exposes a list of categorizers registered on an IShellFolder.
[Vanara.Windows.Shell.ShellFolderCategory](https://github.com/dahall/Vanara/search?l=C%23&q=ShellFolderCategory) | A shell folder category object.
[Vanara.Windows.Shell.ShellIconExtractedEventArgs](https://github.com/dahall/Vanara/search?l=C%23&q=ShellIconExtractedEventArgs) | Event arguments that expose an ID list and associated image.
[Vanara.Windows.Shell.ShellIconExtractor](https://github.com/dahall/Vanara/search?l=C%23&q=ShellIconExtractor) | Class that simplifies extracting icons from items in a Shell Folder.
[Vanara.Windows.Shell.ShellImageList](https://github.com/dahall/Vanara/search?l=C%23&q=ShellImageList) | Represents the System Image List holding images for all shell icons.
[Vanara.Windows.Shell.ShellItem](https://github.com/dahall/Vanara/search?l=C%23&q=ShellItem) | Encapsulates an item in the Windows Shell.
[Vanara.Windows.Shell.ShellItemArray](https://github.com/dahall/Vanara/search?l=C%23&q=ShellItemArray) | A folder or container of `Vanara.Windows.Shell.ShellItem` instances.