tags:

views:

744

answers:

4

How can i get type of file using c#. for example if a file name id "abc.png" and type of file will "PNG Image" same as third column "Type" in window explorer.

+8  A: 

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.

Ash
You may want to correct your post -- szTypeName has the info, not szDisplayName. See http://msdn.microsoft.com/en-us/library/aa453689.aspx => 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.
bobbymcr
@bobbymcr, Done, thanks for the comment.
Ash
+10  A: 

P/invoke to SHGetFileInfo, and check szDisplayName in the returned structure. The result will depend on how you have your file types defined (i.e. it won't be an absolute reference). But it should be fine in most cases. Click here for the c# signature of SHGetFileInfo and example code on pinvoke.net (awesome site that it is)

For an absolute reference you will need something that checks a few bytes in the binary header and compares against a known list of these bytes - I think this is how unix-based systems do it by default.

Dale Halliwell
This is how the `file` utility on unix does it, yes.
Matthew Scharley
+1  A: 

The Win-API function SHGetFileInfo() is your friend. Look here for some code snippets.

Frank Bollack
+2  A: 

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);
    }
}
bobbymcr