Поиск приложения по умолчанию для открытия определенного типа файлов в Windows
Вопрос
Я разрабатываю приложение, ориентированное на .NET Framework 2.0, используя C #, для которого мне нужно иметь возможность найти приложение по умолчанию, которое используется для открытия определенного типа файла.
Я знаю, что, например, если вы просто хотите открыть файл с помощью этого приложения, вы можете использовать что-то вроде:
System.Diagnostics.Process.Start( "C:\...\...\myfile.html" );
чтобы открыть HTML-документ в браузере по умолчанию, или
System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" );
чтобы открыть текстовый файл в текстовом редакторе по умолчанию.
Однако то, что я хочу иметь возможность делать, это открывать файлы, которые не обязательно имеют .текстовый текст расширение (например), в текстовом редакторе по умолчанию, поэтому мне нужно иметь возможность узнать приложение по умолчанию для открытия .текстовый текст файлы, которые позволят мне вызывать его напрямую.
Я предполагаю, что есть какой-то Win32 API, который мне нужно будет P / вызвать, чтобы сделать это, однако быстрый просмотр как в Google, так и в MSDN не выявил ничего интересного;Я нашел очень большое количество совершенно не относящихся к делу страниц, но ничего похожего на то, что я ищу.
Решение
Вы можете проверить в разделе реестра HKEY_CLASSES_ROOT
подробности расширения и действия. Документация для этого находится в MSDN . Кроме того, вы можете использовать интерфейс IQueryAssociations .
Другие советы
Все текущие ответы ненадежны.Реестр - это деталь реализации, и действительно, такой код сломан на моем компьютере с Windows 8.1.Правильный способ сделать это - использовать Win32 API, в частности Ассоциативная строка:
using System.Runtime.InteropServices;
[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(
AssocF flags,
AssocStr str,
string pszAssoc,
string pszExtra,
[Out] StringBuilder pszOut,
ref uint pcchOut
);
[Flags]
public enum AssocF
{
None = 0,
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,
Init_IgnoreUnknown = 0x400,
Init_Fixed_ProgId = 0x800,
Is_Protocol = 0x1000,
Init_For_File = 0x2000
}
public enum AssocStr
{
Command = 1,
Executable,
FriendlyDocName,
FriendlyAppName,
NoOpen,
ShellNewValue,
DDECommand,
DDEIfExec,
DDEApplication,
DDETopic,
InfoTip,
QuickTip,
TileInfo,
ContentType,
DefaultIcon,
ShellExtension,
DropTarget,
DelegateExecute,
Supported_Uri_Protocols,
ProgID,
AppID,
AppPublisher,
AppIconReference,
Max
}
Соответствующая документация:
Пример использования:
static string AssocQueryString(AssocStr association, string extension)
{
const int S_OK = 0;
const int S_FALSE = 1;
uint length = 0;
uint ret = AssocQueryString(AssocF.None, association, extension, null, null, ref length);
if (ret != S_FALSE)
{
throw new InvalidOperationException("Could not determine associated string");
}
var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination
ret = AssocQueryString(AssocF.None, association, extension, null, sb, ref length);
if (ret != S_OK)
{
throw new InvalidOperationException("Could not determine associated string");
}
return sb.ToString();
}
Дох!Конечно.
HKEY_CLASSES_ROOT\.txt
включает ссылку на
HKEY_CLASSES_ROOT\txtfile
который содержит подраздел
HKEY_CLASSES_ROOT\txtfile\shell\open\command
который ссылается на Блокнот.
Разобрались, большое спасибо!
Барт
Вот сообщение в блоге об этом topic. Примеры кода находятся на VB.net, но их должно быть легко перенести на C #.
Вы можете просто запросить реестр. Сначала получите запись по умолчанию в HKEY_CLASSES_ROOT \ .ext
Это даст вам имя класса. Например, .txt имеет значение по умолчанию txtfile
Затем откройте HKEY_CLASSES_ROOT \ txtfile \ Shell \ Open \ Command
Это даст вам команду по умолчанию.
Поздний ответ, но есть хороший пакет NUGET, который обрабатывает ассоциации файлов: Ассоциация файлов
Использовать просто, например, чтобы добавить все разрешенные расширения файлов в контекстное меню:
private void OnMenuSourceFileOpening(object sender, ...)
{ // open a context menu with the associated files + ".txt" files
if (File.Exists(this.SelectedFileName))
{
string fileExt = Path.GetExtension(this.SelectedFileNames);
string[] allowedExtensions = new string[] { fileExt, ".txt" };
var fileAssociations = allowedExtensions
.Select(ext => new FileAssociationInfo(ext));
var progInfos = fileAssociations
.Select(fileAssoc => new ProgramAssociationInfo (fileAssoc.ProgID));
var toolstripItems = myProgInfos
.Select(proginfo => new ToolStripLabel (proginfo.Description) { Tag = proginfo });
// add also the prog info as Tag, for easy access
// when the toolstrip item is selected
// of course this can also be done in one long linq statement
// fill the context menu:
this.contextMenu1.Items.Clear();
this.contextMenuOpenSourceFile.Items.AddRange (toolstripItems.ToArray());
}
}