代码之家  ›  专栏  ›  技术社区  ›  Firoz

获取.NET中的文件类型

  •  11
  • Firoz  · 技术社区  · 16 年前

    例如,如果文件名id为“abc.png”且文件类型为“png图像”,则与窗口资源管理器中的第三列“类型”相同。

    5 回复  |  直到 16 年前
        1
  •  21
  •   bobbymcr    16 年前

    您需要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);
        }
    }
    
        2
  •  11
  •   Ash    16 年前

    您将需要使用windows API SHGetFileInfo function

    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中描述:

    描述文件的类型。

    szDisplayName:以Null结尾的字符串 它出现在Windows shell中,或 包含表示 文件

    Wotsit 有关文件格式的信息。

    链接页面还包含完整的示例C#代码。

        3
  •  10
  •   Dale    16 年前

    P/调用 SHGetFileInfo ,并检查返回结构中的szDisplayName。结果将取决于您如何定义文件类型(即,它不是绝对引用)。但在大多数情况下,这应该是好的。 Click here for the c# signature of SHGetFileInfo and example code on pinvoke.net (这是一个很棒的网站)

    对于绝对引用,您需要检查二进制头中的几个字节,并与这些字节的已知列表进行比较——我认为基于unix的系统默认情况下就是这样做的。

        4
  •  2
  •   Frank Bollack    16 年前

    here 对于一些代码片段。

        5
  •  1
  •   RooiWillie    7 年前

    如果您不想使用P/Invoke,而是想自己查看注册表:

    private Dictionary<string, string> GetRegistryFileTypes()
    {
      Dictionary<string, string> results = new Dictionary<string, string>();
    
      using (RegistryKey rootKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer\KindMap"))
        if (rootKey != null)
          foreach (string currSubKey in rootKey.GetValueNames())
            results.Add(currSubKey, rootKey.GetValue(currSubKey).ToString());
    
      return results;
    }
    

    string fileType = GetRegistryFileTypes()[Path.GetExtension(filePath)];
    
    if (fileType != null && fileType.Length > 0)
      // do whatever here