diff --git a/src/System.Management.Automation/engine/Interop/Windows/SHGetFileInfo.cs b/src/System.Management.Automation/engine/Interop/Windows/SHGetFileInfo.cs new file mode 100644 index 0000000000..5843a1c639 --- /dev/null +++ b/src/System.Management.Automation/engine/Interop/Windows/SHGetFileInfo.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +#if !UNIX +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Keep native struct names.")] + [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Keep native struct names.")] + internal static partial class Windows + { + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct SHFILEINFO + { + internal nint hIcon; + internal int iIcon; + internal uint dwAttributes; + internal fixed char szDisplayName[260]; + internal fixed char szTypeName[80]; + + public static readonly uint s_Size = (uint)sizeof(SHFILEINFO); + } + + [LibraryImport("shell32.dll", EntryPoint = "SHGetFileInfoW", StringMarshalling = StringMarshalling.Utf16)] + internal static partial nint SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); + + internal static int SHGetFileInfo(string pszPath) + { + // flag used to ask to return exe type + const uint SHGFI_EXETYPE = 0x000002000; + var shinfo = new SHFILEINFO(); + return (int)SHGetFileInfo(pszPath, 0, ref shinfo, SHFILEINFO.s_Size, SHGFI_EXETYPE); + } + } +} +#endif diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index c13afb10aa..3e64658644 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -1106,10 +1106,9 @@ namespace System.Management.Automation return false; } - SHFILEINFO shinfo = new SHFILEINFO(); - IntPtr type = SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_EXETYPE); + int type = Interop.Windows.SHGetFileInfo(fileName); - switch ((int)type) + switch (type) { case 0x0: // 0x0 = not an exe @@ -1640,38 +1639,6 @@ namespace System.Management.Automation #endregion - #region Interop for SHGetFileInfo - - private const int SCS_32BIT_BINARY = 0; // A 32-bit Windows-based application - private const int SCS_DOS_BINARY = 1; // An MS-DOS - based application - private const int SCS_WOW_BINARY = 2; // A 16-bit Windows-based application - private const int SCS_PIF_BINARY = 3; // A PIF file that executes an MS-DOS - based application - private const int SCS_POSIX_BINARY = 4; // A POSIX - based application - private const int SCS_OS216_BINARY = 5; // A 16-bit OS/2-based application - private const int SCS_64BIT_BINARY = 6; // A 64-bit Windows-based application. - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private 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; - } - - private const uint SHGFI_EXETYPE = 0x000002000; // flag used to ask to return exe type - - [DllImport("shell32.dll", CharSet = CharSet.Unicode)] - private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, - ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); - - #endregion - #region Minishell Interop private bool _isMiniShell = false;