【问题标题】:Is an Application Associated With a Given Extension?应用程序是否与给定的扩展相关联?
【发布时间】:2012-03-21 08:31:08
【问题描述】:

有时需要让您的应用程序打开文件的默认应用程序。例如,要打开一个 PDF 文件,您可能会使用:

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


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

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


一些扩展(例如 .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;
}

【问题讨论】:

  • 它在寄存器编辑器的某个地方。连同磁铁的处理程序:,邮件:,调用:方案等。如果我没记错的话,它几乎在根目录中

标签: c# file-extension


【解决方案1】:

我建议您遵循David's answer 中的建议,但因为您需要检测关联:

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

DllImport是的

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

例如,另一种选择是遍历注册表(不推荐,因为由于 WoW64 等多个方面很复杂,所以不推荐):

真正的关联存储在HKEY_CLASSES_ROOT\.pdf 指向的键中——在我的例子中是AcroExch.Document,所以我们checkoutHKEY_CLASSES_ROOT\AcroExch.Document。在那里您可以看到(并更改)将使用什么命令来启动该类型的文件:

HKEY_CLASSES_ROOT\AcroExch.Document\shell\open\command

【讨论】:

  • FindExecutable 方法要求存在给定文件,这对于仅获取有关文件类型的信息并不理想。想象一下,当您的方法不是检查特定文件,而实际上只是检查文件类型时,每次都必须创建虚拟文件:/
  • 这个答案对我很有帮助。我有文件,但应用程序更改名称超时。这有助于我获取当前正在运行的应用程序。
【解决方案2】:

@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);

【讨论】:

  • 为什么使用 StringBuilder(1024) 而不是 StringBuilder()?
  • @mggSoft 本机方法 FindExecutable 需要一个缓冲区来返回可执行路径。文档指定此参数必须包含一个有效的非空值,并且假定其长度为 MAX_PATH。因此,虽然 1024 有点矫枉过正,但建议使用 MAX_PATH (260) 的值覆盖默认的 StringBuilder 容量。
  • 此答案适用于 vlc 播放器 mp4 关联,但不适用于 .pdf 在我的情况下由 IE 打开。对于 pdf,我收到了 32 个回复 SE_ERR_NOASSOC。有没有办法在pdf的情况下获得IE?
  • @MatasVaitkevicius 我希望我能为你知道一个更好的答案。
【解决方案3】:

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

【讨论】:

  • 我同意这是最简单的。但是,这种方法的一个主要问题是,您必须以某种方式隐藏正在打开的文档——您并不真正希望用户看到它。
  • 感谢您的建设性意见。我也更喜欢这种方法。我不能,因为我不会让你厌烦。规范非常具体,虽然我不同意其中的原因,但我确实有工作要做。
  • @zmbq 如果您不希望用户看到该文档,那么您只需避免打开它。
  • 我认为 OP 除了打开文件之外还有别的想法。如果他不这样做,那么当然 - 这绝对是要走的路。
  • @Eric 然后,您将享受各种注册表阅读乐趣。要做好这件事,你需要同时查看 HKLM 和 HKCU。您需要注意 WOW64 上的重定向器。您可以在这里获得相当可靠的测试,但您可能无法管理一个万无一失的 100% 准确的重新实现。也许这足以满足PHB。
【解决方案4】:

您将不得不查看注册表以获取该信息。

您可以关注:

HKEY_CLASSES_ROOT\.extension

它通常会导致类似HKEY_CLASSES_ROOT\extfile\Shell\Open\Command

你会来命令打开文件类型。

根据你在做什么,最好只请求原谅(即打开文件并查看)

【讨论】:

  • 你确定够了吗? Visual Studio 某种巫术魔法,其中 .sln 文件具有基于创建它们的 Visual Studio 版本的不同图标。这很诡异,可能没有存储在您所说的位置。
  • @zmbq - 如果您看到HKEY_CLASSES_ROOT,您将看到不同版本的 VS 处理的 sln 文件的不同定义。该图标在DefaultIcon 下定义。基本上,所有的信息都在那里。 stackoverflow.com/questions/4693562/…
【解决方案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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2015-05-27
      相关资源
      最近更新 更多