开发者

Get standard application for txt files (.NET)

开发者 https://www.devze.com 2023-02-12 13:37 出处:网络
In my application I want to open a text file, which has no .txt extension. Is there any way to get the standard applicatio开发者_如何学JAVAn for .txt files in .NET (C#)? Sure I could use \"notepad\",

In my application I want to open a text file, which has no .txt extension. Is there any way to get the standard applicatio开发者_如何学JAVAn for .txt files in .NET (C#)? Sure I could use "notepad", but there might be some people (like me), who prefer another (their standard) editor.


Edit:

The registry key "[HKEY_CLASSES_ROOT]\txtfile\shell\open\command" references notepad, but that's not my standard app for txt files. How do I get the my current standard app for .txt?


The absolute best option is to use ShellExecuteEx, passing the SEE_MASK_CLASSNAME flag, to open this file as if it were a ".txt". This is the only method that will support things like DDE-based and drag-and-drop-based file opening mechanisms.

But if you want to do it yourself (e.g. running with partial trust and can't p/invoke ShellExecuteEx), here's how:

There's another level of indirection. You first have to lookup

HKCR\.txt

Read the default value out of that key, call it txtkey.

Then check

HKCR\ txtkey \shell\open\command

There's also a function to do this for you: AssocQueryString


As far as I know you'll have to access it via P/Invoke, but the cleanest way is probably to create a temporary file with the extension you care about, and call FindExecutable for the temporary file. You can then use that executable to open the file you care about.


My code that include some checks 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
{
    /// <summary>
    /// Usage:  string executablePath = FileAssociation.GetExecFileAssociatedToExtension(pathExtension, "open");
    /// </summary>
    public static class FileAssociation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ext"></param>
        /// <param name="verb"></param>
        /// <returns>Return null if not found</returns>
        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
        }



    }
}


Just try to open the .txt file directly.

Process.Start("MyFile.txt");

It should automatically open with the preferred text editor.

Edit:

Whoops, didn't see it doesn't have .txt extensions. Probably have to check in the registry for the preferred editor?

Edit:

It's here on my computer (Windows 7): HKEY_CLASSES_ROOT\textfile\shell\open\command

0

精彩评论

暂无评论...
验证码 换一张
取 消