应用程序是否与给定的扩展相关联?

Eri*_*ham 13 c# file-extension

有时需要让您的应用程序打开文件的默认应用程序.例如,要打开PDF文件,您可以使用:

System.Diagnostics.Process.Start("Filename.pdf");
Run Code Online (Sandbox Code Playgroud)


要打开图像,您只需使用具有不同文件名的相同代码:

System.Diagnostics.Process.Start("Filename.gif");
Run Code Online (Sandbox Code Playgroud)


一些扩展(例如.gif)几乎总是有一个默认的处理程序,即使在基本的Windows安装中也是如此.但是,某些扩展(例如.pdf)通常没有安装应用程序来处理它们.

在这些情况下,在调用Process.Start(fileName)之前,最好确定应用程序是否与要打开的文件的扩展名相关联.

我想知道如何最好地实现这样的事情:

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;
}
Run Code Online (Sandbox Code Playgroud)

Yah*_*hia 27

我建议按照大卫的答案中的建议,但因为你需要检测一个关联:

要检查文件是否具有关联,您可以使用本机函数FindExecutable,这基本上是Windows资源管理器内部使用的... SE_ERR_NOASSOC如果没有关联,它会提供一个很好的错误代码().成功后,它会提供相应可执行文件的路径.

DllImport是的

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

另一个选择是走路注册表例如(由于像WoW64等几个地方因为复杂而不推荐使用):

真正的关联存储在HKEY_CLASSES_ROOT\.pdf指向的键中- 在我的情况下AcroExch.Document,所以我们结帐HKEY_CLASSES_ROOT\AcroExch.Document.在那里,您可以看到(并更改)将用于启动该类型文件的命令:

HKEY_CLASSES_ROOT\AcroExch.Document\shell\open\command
Run Code Online (Sandbox Code Playgroud)

  • “FindExecutable”方法要求给定文件存在,这对于仅获取有关文件类型的信息并不理想。想象一下,当您的方法不是检查特定文件而实际上只是检查文件类型时,每次执行此操作时都必须创建虚拟文件:/ (2认同)

Eri*_*ham 6

@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);
Run Code Online (Sandbox Code Playgroud)

  • @mggSoft 本机方法 FindExecutable 需要一个缓冲区来返回可执行路径。文档指定 _This 参数必须包含有效的非空值,并且假定长度为 MAX_PATH_。因此,虽然 1024 有点矫枉过正,但建议使用 MAX_PATH (260) 的值覆盖默认的 StringBuilder 容量。 (3认同)

Dav*_*nan 5

在这种情况下,最好的方法是尝试打开文档并检测故障.尝试预测文件关联是否到位只会导致您重新实现shell执行API.因为它们已经存在,所以很难完全正确而且不必要!