Как я могу получить тип файла с помощью С#. например, если имя файла "abc.png" и тип файла будут "PNG Image" такими же, как и третий столбец "Тип" в проводнике окон.
Получить тип файла в .NET.
Ответ 1
Вам нужно будет использовать API окон Функция SHGetFileInfo
В структуре вывода szTypeName содержится имя, которое вы ищете.
[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;
};
Обратите внимание, что это просто текущее "дружественное имя", которое хранится в реестре Windows, это всего лишь ярлык (но, вероятно, достаточно хорош для вашей ситуации).
Разница между szTypeName и szDisplayName описана в MSDN:
szTypeName: строка с нулевым завершением, которая описывает тип файла.
szDisplayName: строка с нулевым завершением который содержит имя файла как он появляется в оболочке Windows или путь и имя файла, который содержит значок, представляющий файл.
Для более точного определения типа файла вам нужно будет прочитать первый кусок байтов каждого файла и сравнить их с опубликованными спецификациями файлов. Для информации о форматах файлов см. Сайт Wotsit.
Связанная страница также содержит полный пример кода на С#.
Ответ 2
Вам понадобится P/Invoke для SHGetFileInfo, чтобы получить информацию о типе файла. Вот полный образец:
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);
}
}
Ответ 3
P/вызывать SHGetFileInfo и проверять имя szDisplayName в возвращаемой структуре. Результат будет зависеть от того, как ваши типы файлов определены (т.е. Это не будет абсолютной ссылкой). Но в большинстве случаев это должно быть хорошо. Нажмите здесь, чтобы получить подпись С# SHGetFileInfo и пример кода на pinvoke.net (удивительный сайт, который он)
Для абсолютной ссылки вам понадобится что-то, что проверяет несколько байтов в двоичном заголовке и сравнивается с известным списком этих байтов. Я думаю, что по умолчанию это делают системы на основе unix.
Ответ 4
Функция Win-API SHGetFileInfo() - ваш друг. Посмотрите здесь для некоторых фрагментов кода.