Поиск приложения по умолчанию для открытия определенного типа файлов в Windows

StackOverflow https://stackoverflow.com/questions/162331

  •  03-07-2019
  •  | 
  •  

Вопрос

Я разрабатываю приложение, ориентированное на .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, который обрабатывает ассоциации файлов: Ассоциация файлов

Связь файлов 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());
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top