4

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.

vulkanino
  • 9,074
  • 7
  • 44
  • 71
Zavael
  • 2,383
  • 1
  • 32
  • 44
  • see link http://stackoverflow.com/questions/770023/how-do-i-get-file-type-information-based-on-extention-not-mime-in-c-sharp - you need FriendlyDocName – Lonli-Lokli Mar 07 '12 at 12:14
  • 1
    Please understand that not ever extension will have this information. The first application that uses said application must register this information in the registry. – Security Hound Mar 07 '12 at 12:27

4 Answers4

4

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("...").

Christian.K
  • 47,778
  • 10
  • 99
  • 143
1

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_TY PENAME);
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);
}
}
SeToY
  • 5,777
  • 12
  • 54
  • 94
1

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 "";
}
L.B
  • 114,136
  • 19
  • 178
  • 224
0

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

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

Vikram
  • 8,235
  • 33
  • 47
  • 1
    That only shows how to retrieve the Icon, not the file type name. While the additional effort is minor, it would be helpful if you actually show what to do, rather than just posting the link. – Christian.K Mar 07 '12 at 12:03