Description
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
Type
Projects
Status