如何在C#中获取与文件扩展名相关联的推荐程序

10

我希望能够通过Win32 API获取与文件扩展名相关联的程序路径。

  1. "打开方式"菜单中显示的程序列表
  2. 在"打开方式..."对话框中显示为推荐选项的程序列表。

更新:

假设我在我的计算机上安装了office11和office12,.xls文件的默认程序是office 11。如果查看HKEY_CLASSES_ROOT\Excel.Sheet.8\shell\Open\command,会有指向office11 Excel.exe的路径,但是当我右键单击文件时,在"打开方式"菜单中可以选择office12。那么这个关联存储在哪里呢?

我正在使用C#。

谢谢。


它在注册表中,所以也许你应该尝试从注册表中读取相关程序。 - Fender
1
看这里。你必须从注册表中获取信息https://dev59.com/NnVC5IYBdhLWcg3wsTVi - Orhan Cinar
1
可能是重复的问题:Windows:列出并启动与扩展名相关联的应用程序 - Hans Passant
@Oded:首先我查看了注册表,但那里只有当用户双击文件时运行的程序,我的目标是从“打开方式”对话框或同一下拉菜单中列出替代程序。 - Alexander
@Hans Passant:那个问题是关于获取“主要”关联的,我需要获取推荐的关联。 - Alexander
3个回答

14

我写了一个小程序:

public IEnumerable<string> RecommendedPrograms(string ext)
{
  List<string> progs = new List<string>();

  string baseKey = @"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." + ext;

  using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithList"))
  {
    if (rk != null)
    {
      string mruList = (string)rk.GetValue("MRUList");
      if (mruList != null)
      {
        foreach (char c in mruList.ToString())
          progs.Add(rk.GetValue(c.ToString()).ToString());
      }
    }
  }

  using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithProgids"))
  {
    if (rk != null)
    {
      foreach (string item in rk.GetValueNames())
        progs.Add(item);
    }
    //TO DO: Convert ProgID to ProgramName, etc.
  }

  return progs;
  }

这样调用:

foreach (string prog in RecommendedPrograms("vb"))
{
  MessageBox.Show(prog);
}

1
感谢您抽出时间编写这个程序,但是似乎从注册表中获取这些信息的方式非常混乱...例如关于xls扩展名:该程序不仅返回推荐的程序,还返回曾经打开过此类文件的所有应用程序(甚至包括我编写的应用程序),而且它只返回一个progrId Excel.Sheet.8,我尝试在注册表中搜索它,但只找到了Office 11 Excel的路径...无论如何,再次感谢您提供的好答案。这比没有要好得多。 - Alexander
还不错,但是无法获取程序名称 :/ - StinkyCat

3
如果您想在系统上以编程方式将文件类型与您的应用程序关联起来,但不喜欢自己深入挖掘注册表的想法,那么本文和代码就适合您。请参考System File Association

谢谢您的帮助,但我需要获取关联,而不是设置。我查看了源代码,但仍然找不到方法。 - Alexander

0

我改进了LarsTech的方法。现在它返回程序路径。

public List<string> RecommendedPrograms(string ext)
{
  //Search programs names:
  List<string> names = new List<string>();
  string baseKey = @"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." + ext;
  string s;

  using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithList"))
  {
    if (rk != null)
    {
      string mruList = (string)rk.GetValue("MRUList");
      if (mruList != null)
      {
        foreach (char c in mruList)
        {
          s = rk.GetValue(c.ToString()).ToString();
          if (s.ToLower().Contains(".exe"))
            names.Add(s);
        }
      }
    }
  }

  if (names.Count == 0)
    return names;

  //Search paths:
  List<string> paths = new List<string>();
  baseKey = @"Software\Classes\Applications\{0}\shell\open\command";

  foreach (string name in names)
    using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(String.Format(baseKey, name)))
    {
      if (rk != null)
      {
        s = rk.GetValue("").ToString();
        s = s.Substring(1, s.IndexOf("\"", 2) - 1); //remove quotes
        paths.Add(s);
      }
    }

  if (paths.Count > 0)
    return paths;

  //Search pathes for Windows XP:
  foreach (string name in names)
    using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(String.Format(baseKey, name)))
    {
      if (rk != null)
      {
        s = rk.GetValue("").ToString();
        s = s.Substring(1, s.IndexOf("\"", 2) - 1); //remove quotes
        paths.Add(s);
      }
    }

  return paths;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接