如何根据扩展名获取文件类型信息? c#中的(不是MIME)

如何获得基于扩展的常规文件类型描述,如资源管理器吗? 所以不是MIME,而是最终用户看到的信息,比如。

.doc = Microsoft Office Word 97 – 2003文档.zip = ZIP文件.avi =video文件。

我怎样才能获得似乎可用的“辅助”信息,我猜它不是基于扩展的。 就像在“video文件”上一样,它可以为您提供电影的“长度”或者在doc文件中为您提供了多少页面等等。

谢谢Dan,好吧..这回答了我的第一个问题。 可悲的不是第二个。 注意:并非一切都打印..致PInvoke.net的积分

using System; using System.Runtime.InteropServices; using System.Text; using System.Diagnostics; namespace WindowsFormsApplication1 { static class Program { [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, [In][Out] ref uint pcchOut); ///  /// The main entry point for the application. ///  [STAThread] static void Main() { Debug.WriteLine(FileExtentionInfo(AssocStr.Command, ".doc"), "Command"); Debug.WriteLine(FileExtentionInfo(AssocStr.DDEApplication, ".doc"), "DDEApplication"); Debug.WriteLine(FileExtentionInfo(AssocStr.DDEIfExec, ".doc"), "DDEIfExec"); Debug.WriteLine(FileExtentionInfo(AssocStr.DDETopic, ".doc"), "DDETopic"); Debug.WriteLine(FileExtentionInfo(AssocStr.Executable, ".doc"), "Executable"); Debug.WriteLine(FileExtentionInfo(AssocStr.FriendlyAppName, ".doc"), "FriendlyAppName"); Debug.WriteLine(FileExtentionInfo(AssocStr.FriendlyDocName, ".doc"), "FriendlyDocName"); Debug.WriteLine(FileExtentionInfo(AssocStr.NoOpen, ".doc"), "NoOpen"); Debug.WriteLine(FileExtentionInfo(AssocStr.ShellNewValue, ".doc"), "ShellNewValue"); // DDEApplication: WinWord //DDEIfExec: Ñﻴ߾ // DDETopic: System // Executable: C:\Program Files (x86)\Microsoft Office\Office12\WINWORD.EXE // FriendlyAppName: Microsoft Office Word // FriendlyDocName: Microsoft Office Word 97 - 2003 Document } public static string FileExtentionInfo(AssocStr assocStr, string doctype) { uint pcchOut = 0; AssocQueryString(AssocF.Verify, assocStr, doctype, null, null, ref pcchOut); StringBuilder pszOut = new StringBuilder((int)pcchOut); AssocQueryString(AssocF.Verify, assocStr, doctype, null, pszOut, ref pcchOut); return pszOut.ToString(); } [Flags] public enum AssocF { Init_NoRemapCLSID = 0x1, Init_ByExeName = 0x2, Open_ByExeName = 0x2, Init_DefaultToStar = 0x4, Init_DefaultToFolder = 0x8, NoUserSettings = 0x10, NoTruncate = 0x20, Verify = 0x40, RemapRunDll = 0x80, NoFixUps = 0x100, IgnoreBaseClass = 0x200 } public enum AssocStr { Command = 1, Executable, FriendlyDocName, FriendlyAppName, NoOpen, ShellNewValue, DDECommand, DDEIfExec, DDEApplication, DDETopic } } } 

直接从注册表中读取这样的内容通常是一个坏主意(请参阅Raymond Chen的博客了解所有血腥细节 )。 在这种特殊情况下,您需要的API是AssocQueryString中的AssocQueryString

这是C ++代码:

 TCHAR buf[1024]; DWORD sz = sizeof(buf) / sizeof(TCHAR); AssocQueryString(ASSOCF_INIT_DEFAULTTOSTAR, ASSOCSTR_FRIENDLYDOCNAME, L".sql", NULL, buf, &sz); 

您可以通过C ++ / CLI从C#中使用它来展示一个友好的.NET友好API; 或通过P / Invoke直接调用它。

XP中未知文件类型的一些额外的if ..当使用除了FriendlyDocName之外的任何东西时,可能无法真正给出正确的结果,但仅作为示例:

 public static string FileExtentionInfo(AssocStr assocStr, string doctype) { if ((doctype.Length <= 1) || !doctype.StartsWith(".")) return ""; uint pcchOut = 0; AssocQueryString(AssocF.Verify, assocStr, doctype, null, null, ref pcchOut); if (pcchOut == 0) return (doctype.Trim('.').ToUpper() + " File"); StringBuilder pszOut = new StringBuilder((int)pcchOut); AssocQueryString(AssocF.Verify, assocStr, doctype, null, pszOut, ref pcchOut); return pszOut.ToString(); } 

我的代码包括检查以防止一些常见的错误…希望它有所帮助:-)

 using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace HQ.Util.Unmanaged { ///  /// Usage: string executablePath = FileAssociation.GetExecFileAssociatedToExtension(pathExtension, "open"); ///  public static class FileAssociation { ///  /// ///  ///  ///  /// Return null if not found public static string GetExecFileAssociatedToExtension(string ext, string verb = null) { if (ext[0] != '.') { ext = "." + ext; } string executablePath = FileExtentionInfo(AssocStr.Executable, ext, verb); // Will only work for 'open' verb if (string.IsNullOrEmpty(executablePath)) { executablePath = FileExtentionInfo(AssocStr.Command, ext, verb); // required to find command of any other verb than 'open' // Extract only the path if (!string.IsNullOrEmpty(executablePath) && executablePath.Length > 1) { if (executablePath[0] == '"') { executablePath = executablePath.Split('\"')[1]; } else if (executablePath[0] == '\'') { executablePath = executablePath.Split('\'')[1]; } } } // Ensure to not return the default OpenWith.exe associated executable in Windows 8 or higher if (!string.IsNullOrEmpty(executablePath) && File.Exists(executablePath) && !executablePath.ToLower().EndsWith(".dll")) { if (executablePath.ToLower().EndsWith("openwith.exe")) { return null; // 'OpenWith.exe' is th windows 8 or higher default for unknown extensions. I don't want to have it as associted file } return executablePath; } return executablePath; } [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, [In][Out] ref uint pcchOut); private static string FileExtentionInfo(AssocStr assocStr, string doctype, string verb) { uint pcchOut = 0; AssocQueryString(AssocF.Verify, assocStr, doctype, verb, null, ref pcchOut); Debug.Assert(pcchOut != 0); if (pcchOut == 0) { return ""; } StringBuilder pszOut = new StringBuilder((int)pcchOut); AssocQueryString(AssocF.Verify, assocStr, doctype, verb, pszOut, ref pcchOut); return pszOut.ToString(); } [Flags] public enum AssocF { Init_NoRemapCLSID = 0x1, Init_ByExeName = 0x2, Open_ByExeName = 0x2, Init_DefaultToStar = 0x4, Init_DefaultToFolder = 0x8, NoUserSettings = 0x10, NoTruncate = 0x20, Verify = 0x40, RemapRunDll = 0x80, NoFixUps = 0x100, IgnoreBaseClass = 0x200 } public enum AssocStr { Command = 1, Executable, FriendlyDocName, FriendlyAppName, NoOpen, ShellNewValue, DDECommand, DDEIfExec, DDEApplication, DDETopic } } }