Get standard application for txt files (.NET)
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
精彩评论