如何在.NET中获取文件扩展名的描述

时间:2010-09-23 15:40:25

标签: .net windows

HI,

Windows提供文件扩展名的说明,例如.cpl文件的“控制面板项”和.daa文件的“PowerISO文件”。有什么办法可以在.NET中获取这些数据吗?我使用C#但可以读取所有其他.NET语言。还有一种方法可以获得扩展的默认图标吗?任何帮助将不胜感激。

提前致谢

5 个答案:

答案 0 :(得分:13)

您可以使用SHGetFileInfo API获取该信息。这是一个包装方法:

    public static string GetFileTypeDescription(string fileNameOrExtension)
    {
        SHFILEINFO shfi;
        if (IntPtr.Zero != SHGetFileInfo(
                            fileNameOrExtension,
                            FILE_ATTRIBUTE_NORMAL,
                            out shfi,
                            (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                            SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME))
        {
            return shfi.szTypeName;
        }
        return null;
    }

    [DllImport("shell32")]
    private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);

    [StructLayout(LayoutKind.Sequential)]
    private 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;
    }

    private const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
    private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
    private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
    private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
    private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
    private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040;
    private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
    private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
    private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
    private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
    private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
    private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
    private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
    private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
    private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000;

    private const uint SHGFI_ICON = 0x000000100;     // get icon
    private const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
    private const uint SHGFI_TYPENAME = 0x000000400;     // get type name
    private const uint SHGFI_ATTRIBUTES = 0x000000800;     // get attributes
    private const uint SHGFI_ICONLOCATION = 0x000001000;     // get icon location
    private const uint SHGFI_EXETYPE = 0x000002000;     // return exe type
    private const uint SHGFI_SYSICONINDEX = 0x000004000;     // get system icon index
    private const uint SHGFI_LINKOVERLAY = 0x000008000;     // put a link overlay on icon
    private const uint SHGFI_SELECTED = 0x000010000;     // show icon in selected state
    private const uint SHGFI_ATTR_SPECIFIED = 0x000020000;     // get only specified attributes
    private const uint SHGFI_LARGEICON = 0x000000000;     // get large icon
    private const uint SHGFI_SMALLICON = 0x000000001;     // get small icon
    private const uint SHGFI_OPENICON = 0x000000002;     // get open icon
    private const uint SHGFI_SHELLICONSIZE = 0x000000004;     // get shell size icon
    private const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
    private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;     // use passed dwFileAttribute

(大多数常量实际上并没有在该代码中使用,但无论如何我都会使用它们以防您根据自己的特定需求调整代码)

答案 1 :(得分:0)

扩展名与HKEY_CLASSES_ROOT键相关联。因此,您需要打开注册表并找到您感兴趣的值。您还应该能够在那里找到默认图标。

Here是一个示例项目(我没试过)。

答案 2 :(得分:0)

让我们说你的扩展名是.xyz要显示大多数用户友好的文字,例如“控制面板项目”,你应该做两件事:

  1. 转到HKEY_CLASSES_ROOT并搜索节点xyzfile。检查“cplfile”
  2. 如果不存在,您可以在同一个地方获得关联,但节点是.xyz。它将告诉哪些应用程序打开它,以便您可以获得该名称。

答案 3 :(得分:0)

您可以像这样搜索注册表:

  • HKEY_CLASSES_ROOT中搜索扩展程序的默认值。例如,HKEY_CLASSES_ROOT\.txt的默认值为txtfile
  • 然后搜索上一个结果的默认值:例如,HKEY_CLASSES_ROOT\txtfile的默认值为Text Document

两次搜索后,答案为文字广告

您可以按RegEdit测试任何其他扩展程序。

访问此链接:http://www.codeproject.com/KB/cs/GetFileTypeAndIcon.aspx?display=Print

这是这两个搜索的实现:

public static class Helper
{
    public static string GetFileDescription(string fileName)
    {
        if (fileName == null)
        {
            throw new ArgumentNullException("fileName");
        }

        RegistryKey registryKey1 = null;
        RegistryKey registryKey2 = null;
        try
        {
            FileInfo fileInfo = new FileInfo(fileName);

            if (string.IsNullOrEmpty(fileInfo.Extension))
            {
                return string.Empty;
            }

            string extension = fileInfo.Extension.ToLowerInvariant();

            registryKey1 = Registry.ClassesRoot.OpenSubKey(extension);
            if (registryKey1 == null)
            {
                return string.Empty;
            }

            object extensionDefaultObject = registryKey1.GetValue(null);
            if (!(extensionDefaultObject is string))
            {
                return string.Empty;
            }

            string extensionDefaultValue = (string)extensionDefaultObject;

            registryKey2 = Registry.ClassesRoot.OpenSubKey(extensionDefaultValue);
            if (registryKey2 == null)
            {
                return string.Empty;
            }

            object fileDescriptionObject = registryKey2.GetValue(null);
            if (!(fileDescriptionObject is string))
            {
                return string.Empty;
            }

            string fileDescription = (string)fileDescriptionObject;
            return fileDescription;
        }
        catch (Exception)
        {
            return null;
        }
        finally
        {
            if (registryKey2 != null)
            {
                registryKey2.Close();
            }

            if (registryKey1 != null)
            {
                registryKey1.Close();
            }
        }
    }
}

答案 4 :(得分:0)

要使用{ "folders": [ { "path": ".." }, { "path": "../../usr/local/lib/python3.9/site-packages" } ], "settings": {} } ,文件必须存在于磁盘上。如果只有文件的名称,甚至只有扩展名,则需要直接从注册表中获取信息:

SHGetFileInfo

如果注册表中没有给定文件扩展名的适当条目,则此方法将仅返回public static string GetFileTypeDisplayName(string extension) => Registry.ClassesRoot.OpenSubKey(extension)?.GetValue(null) is string keyName ? Registry.ClassesRoot.OpenSubKey(keyName)?.GetValue(null) as string : null;