dahall / Vanara

A set of .NET libraries for Windows implementing PInvoke calls to many native Windows APIs with supporting wrappers.
MIT License
1.81k stars 196 forks source link

EnumerateChildIds throws NullReferenceException if children not available #488

Open zhuxb711 opened 2 months ago

zhuxb711 commented 2 months ago

https://github.com/dahall/Vanara/blob/3da05fe4d87bc5de96527fad5c9b7e6058690deb/Windows.Shell.Common/ShellObjects/ShellFolder.cs#L213

StackTrace:
   at System.Runtime.InteropServices.Marshal.ReleaseComObject(Object o)
   at Vanara.Windows.Shell.ShellFolder.<EnumerateChildIds>d__23.<>m__Finally1()
   at Vanara.Windows.Shell.ShellFolder.<EnumerateChildIds>d__23.MoveNext()
   at Vanara.Windows.Shell.ShellFolder.<EnumerateChildren>d__22.MoveNext()

The root cause should be if iShellFolder.EnumObjects(parentWindow, (SHCONTF)filter, out var eo).Failed == true then it would not yield break.

Corrent one should be:

    public IEnumerable<PIDL> EnumerateChildIds(FolderItemFilter filter /*= FolderItemFilter.Folders | FolderItemFilter.IncludeHidden | FolderItemFilter.NonFolders | FolderItemFilter.IncludeSuperHidden */, HWND parentWindow = default, int fetchSize = 20)
    {
        if (iShellFolder.EnumObjects(parentWindow, (SHCONTF)filter, out var eo).Failed)
            {
                    Debug.WriteLine($"Unable to enum children in folder.");
                    yield break;
                }

        try
        {
            foreach (PIDL p in eo!.Enumerate(fetchSize))
                yield return p;
        }
        finally { Marshal.ReleaseComObject(eo!); } // Maybe should not call ReleaseComObject in case RCW exception
    }
tajbender commented 2 months ago

I'll take a look at it 👍