Get file type in .NET

You'll need to P/Invoke to SHGetFileInfo to get file type information. Here is a complete sample:

using System;
using System.Runtime.InteropServices;

static class NativeMethods
{
    [StructLayout(LayoutKind.Sequential)]
    public 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;
    };

    public static class FILE_ATTRIBUTE
    {
        public const uint FILE_ATTRIBUTE_NORMAL = 0x80;
    }

    public static class SHGFI
    {
        public const uint SHGFI_TYPENAME = 0x000000400;
        public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
    }

    [DllImport("shell32.dll")]
    public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
}

class Program
{
    public static void Main(string[] args)
    {
        NativeMethods.SHFILEINFO info = new NativeMethods.SHFILEINFO();

        string fileName = @"C:\Some\Path\SomeFile.png";
        uint dwFileAttributes = NativeMethods.FILE_ATTRIBUTE.FILE_ATTRIBUTE_NORMAL;
        uint uFlags = (uint)(NativeMethods.SHGFI.SHGFI_TYPENAME | NativeMethods.SHGFI.SHGFI_USEFILEATTRIBUTES);

        NativeMethods.SHGetFileInfo(fileName, dwFileAttributes, ref info, (uint)Marshal.SizeOf(info), uFlags);

        Console.WriteLine(info.szTypeName);
    }
}

You will need to use the windows API SHGetFileInfo function

In the output structure, szTypeName contains the name you are looking for.

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public 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;
};

Note that this is simply the current "Friendly name" as stored in the Windows Registry, it is just a label (but is probably good enough for your situation).

The difference between szTypeName and szDisplayName is described at MSDN:

szTypeName: Null-terminated string that describes the type of file.

szDisplayName: Null-terminated string that contains the name of the file as it appears in the Windows shell, or the path and name of the file that contains the icon representing the file.

For more accurate determination of file type you would need to read the first chunk of bytes of each file and compare these against published file specifications. See a site like Wotsit for info on file formats.

The linked page also contains full example C# code.

Tags:

C#

.Net

File