Является ли приложение связанным с данным расширением?

Иногда желательно, чтобы ваше приложение открыло приложение по умолчанию для файла. Например, чтобы открыть файл PDF, который вы можете использовать:

System.Diagnostics.Process.Start("Filename.pdf");


Чтобы открыть изображение, вы просто используете тот же код с другим именем файла:

System.Diagnostics.Process.Start("Filename.gif");


Некоторые расширения (например,.gif) всегда имеют обработчик по умолчанию, даже при базовой установке Windows. Однако некоторые расширения (например,.pdf) часто не имеют приложения для их обработки.

В этих случаях было бы желательно определить, связано ли приложение с расширением файла, который вы хотите открыть, прежде чем сделать вызов Process.Start(имя_файла).

Мне интересно, как лучше всего реализовать что-то вроде этого:

static bool ApplicationAssociated(string extension)
{
    var extensionHasAssociatedApplication = false;

    var condition = // Determine if there is an application installed that is associated with the provided file extension.;
    if (condition)
    {
        extensionHasAssociatedApplication = true;
    }

    return extensionHasAssociatedApplication;
}

Ответ 1

Я бы посоветовал следовать рекомендациям David answer, но так как вам нужно обнаружить связь:

Чтобы проверить, имеет ли файл связь, вы можете использовать встроенную функцию FindExecutable, которая в основном используется Windows Explorer. он дает хороший код ошибки (SE_ERR_NOASSOC), если нет никакой связи. После успеха он дает путь к соответствующему исполняемому файлу.

Те DllImport для него

[DllImport("shell32.dll")]
static extern int FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult);

Другой вариант - это, например, прогуляться по реестру (не рекомендуется, так как сложный из-за нескольких aspets, таких как WoW64 и т.д.):

Действительная ассоциация сохраняется в ключе, на которое HKEY_CLASSES_ROOT\.pdf указывает - в моем случае AcroExch.Document, поэтому мы проверяем HKEY_CLASSES_ROOT\AcroExch.Document. Там вы можете увидеть (и изменить), какая команда будет использоваться для запуска этого типа файла:

HKEY_CLASSES_ROOT\AcroExch.Document\shell\open\command

Ответ 2

В такой ситуации лучшим способом является попытка открыть документ и обнаружить сбой. Попытка предсказать, существует ли ассоциация файлов, просто приводит к повторному выполнению API-интерфейсов оболочки. Очень трудно понять, что это правильно и довольно бесполезно, поскольку они уже существуют!

Ответ 3

@Yahia получает кивок. Я отправляю свое быстрое решение для потомков, чтобы вы могли видеть, с чем я пошел. В этом коде есть много возможных улучшений, но это даст вам идею:

public static bool HasExecutable(string path)
{
    var executable = FindExecutable(path);
    return !string.IsNullOrEmpty(executable);
}

private static string FindExecutable(string path)
{
    var executable = new StringBuilder(1024);
    FindExecutable(path, string.Empty, executable);
    return executable.ToString();
}

[DllImport("shell32.dll", EntryPoint = "FindExecutable")]
private static extern long FindExecutable(string lpFile, string lpDirectory, StringBuilder lpResult);

Ответ 4

Вы также можете просмотреть реестр, чтобы получить эту информацию.

Вы можете следовать из:

HKEY_CLASSES_ROOT\.extension

и обычно это приводит к чему-то вроде HKEY_CLASSES_ROOT\extfile\Shell\Open\Command

и вы придете к команде, чтобы открыть тип файла.

В зависимости от того, что вы делаете, может быть идеальным просто попросить прощения (то есть просто откройте файл и посмотрите)

Ответ 5

Вся эта информация живет в реестре.. вы можете перейти к HKEY_CLASSES_ROOT, найти расширение и перейти оттуда, чтобы найти обработчик по умолчанию. Но в зависимости от типа файла и связанного с ним обработчика (ов) вам нужно пробираться в CLSID и еще что... вы, вероятно, лучше избегаете исключения.

Ответ 6

Эта информация находится в реестре. Например:

# Mount the HKCR drive in powershell
ps c:\> new-psdrive hkcr registry hkey_classes_root
ps c:\> cd hkcr:\.cs

# get default key for .cs
PS hkcr:\.cs> gp . ""
(default)    : VisualStudio.cs.10.0
...

# dereference the "open" verb
PS hkcr:\.cs> dir ..\VisualStudio.cs.10.0\shell\open

    Hive: hkey_classes_root\VisualStudio.cs.10.0\shell\open

Name                           Property
----                           --------
Command                        (default) : "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" /dde
ddeexec                        (default) : Open("%1")