How do I get File Type Information based on extension? (not MIME) in c#

后端 未结 5 1955
失恋的感觉
失恋的感觉 2020-12-01 12:23

How do I get the general File type description based on extension like Explorer does it? So not MIME but the information that the end-user sees, like.

.doc = Microso

5条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-01 13:19

    My code that include check to prevent from some common errors... Hope it helps :-)

    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
            }
    
    
    
        }
    }
    

提交回复
热议问题