Skip to content

PInvoke issue with SHGetFileInfo w/ SHGFI_ICON #116151

Closed
@Androvald

Description

@Androvald

Description

In .NET 9 and 10 calling SHGetFileInfo with the request for an icon crashes the application with exit code -1073740791 (0xc0000409) - stack overflow. This does not happen in other versions of .NET (Tested 6 and 8 specifically).

I found this after debugging the new Powertoys Command palette, since it was crashing whenever I entered anything in the search box.

Reproduction Steps

using System.Runtime.InteropServices;

class Program
{
    public static void Main()
    {

        const uint SHGFI_ICON = 0x000000100;
        const uint SHGFI_DISPLAYNAME = 0x000000200;

        var fileInfo = new SHFILEINFO();
        Console.WriteLine("Starting");
        Console.WriteLine(Marshal.SizeOf(fileInfo));
        var result = SHGetFileInfo(@"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk", 0, ref fileInfo, (uint)Marshal.SizeOf(fileInfo), SHGFI_ICON);
        Console.WriteLine(".NET 9 does not reach here.");
        DestroyIcon(fileInfo.hIcon);
        Console.WriteLine(result);
        Console.WriteLine(fileInfo.szDisplayName);
    }

    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
    static extern nint SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern bool DestroyIcon(IntPtr hIcon);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct SHFILEINFO
    {
        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    }
}

Expected behavior

Return a handle to an icon in the struct.

Actual behavior

Looks like a stack overflow, since it aborts the process, and does not allow the debugger to do anything.

Regression?

Works in .NET 8 and prior.

Known Workarounds

None

Configuration

Windows 11, 24H2 build 26100.4061 on Intel Core i7-13700K in x64 mode.
Tested .NET 9.0.5 w/ sdk 9.0.300 and .NET 10 preview 4.
Not sure if it's specific to this configuration.

Other information

For some reason this does not crash in Linqpad 8, even in .NET 9 mode. I'm not sure what is different there.
Other options do seem to work fine. Such as the display name comes through just fine if requested. But it breaks the moment you request an icon.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions