andrejb-dev
andrejb-dev

Reputation: 2468

How to get the file type name?

I want to get in my c# app the name of the file type, that is shown in file properties in windows... for example .log file has the type as LOG file (.log) or .bat has Batch file for Windows (.bat)(translated from my lang, so maybe not accurate).

Please, where can i find this info? or how to get to this? i found Get-Registered-File-Types-and-Their-Associated-Ico article, where the autor shows how to get the icon, but not the type name of file that is showed in OS.

Upvotes: 4

Views: 4496

Answers (4)

SeToY
SeToY

Reputation: 5895

You can get this information using the SHGetFileInfo.

using System;
using System.Runtime.InteropServices;

namespace GetFileTypeAndDescription
{

class Class1
{
  [STAThread]
  static void Main(string[] args)
  {
    SHFILEINFO shinfo = new SHFILEINFO();
    IntPtr i = Win32.SHGetFileInfo(@"d:\temp\test.xls", 0, ref
      shinfo,(uint)Marshal.SizeOf(shinfo),Win32.SHGFI_TYPENAME);
    string s = Convert.ToString(shinfo.szTypeName.Trim());
    Console.WriteLine(s);
  }
}

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

class Win32
{
  public const uint SHGFI_DISPLAYNAME = 0x00000200;
  public const uint SHGFI_TYPENAME = 0x400;
  public const uint SHGFI_ICON = 0x100;
  public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
  public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

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

}

Upvotes: 1

L.B
L.B

Reputation: 116178

You can read that info from the registry

use like GetDescription("cpp") or GetDescription(".xml")

public static string ReadDefaultValue(string regKey)
{
    using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(regKey, false))
    {
        if (key != null)
        {
            return key.GetValue("") as string;
        }
    }
    return null;
}

public static string GetDescription(string ext)
{
    if (ext.StartsWith(".") && ext.Length > 1) ext = ext.Substring(1);

    var retVal = ReadDefaultValue(ext + "file");
    if (!String.IsNullOrEmpty(retVal)) return retVal;


    using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("." + ext, false))
    {
        if (key == null) return "";

        using (var subkey = key.OpenSubKey("OpenWithProgids"))
        {
            if (subkey == null) return "";

            var names = subkey.GetValueNames();
            if (names == null || names.Length == 0) return "";

            foreach (var name in names)
            {
                retVal = ReadDefaultValue(name);
                if (!String.IsNullOrEmpty(retVal)) return retVal;
            }
        }
    }

    return "";
}

Upvotes: 1

Christian.K
Christian.K

Reputation: 49290

You have to call the respective Shell function SHGetFileInfo, which is a native Win32 API.

class NativeMethods
{
    private const int FILE_ATTRIBUTE_NORMAL = 0x80;
    private const int SHGFI_TYPENAME = 0x400;

    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
    private static extern IntPtr SHGetFileInfo(
        string pszPath,
        int dwFileAttributes,
        ref  SHFILEINFO shinfo,
        uint cbfileInfo,
        int uFlags);


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct SHFILEINFO
    {
        public SHFILEINFO(bool b)
        {
            hIcon = IntPtr.Zero;
            iIcon = 0;
            dwAttributes = 0;
            szDisplayName = "";
            szTypeName = "";
        }

        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 string GetShellFileType(string fileName)
    {
        var shinfo = new SHFILEINFO(true);
        const int flags = SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES;

        if (SHGetFileInfo(fileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags) == IntPtr.Zero)
        {
            return "File";
        }

        return shinfo.szTypeName;
    }
}

Then, simply call NativeMethods.GetShellFileType("...").

Upvotes: 4

Vikram
Vikram

Reputation: 8333

you have to use the shgetfileinfo, see below link for some code:

http://www.pinvoke.net/default.aspx/shell32.shgetfileinfo

Upvotes: 0

Related Questions