10

I want to get path to the programs that associated with file extension, preferably through Win32 API.

  1. List of programs that appears in "Open With" menu item
  2. List of programs that appears as recommended in "Open With..." dialog.

UPD:

Assume that i have office11 and office12 installed on my machine, default program for .xls is office 11. If look at HKEY_CLASSES_ROOT\Excel.Sheet.8\shell\Open\command there is a path to office11 excel.exe, but when i right click on file i can choose office12 in Open With menu item. So where is this association stored?

I'm using C#.

Thanks.

Alexander
  • 1,287
  • 1
  • 15
  • 34
  • it's in the registry, so maybe you should just try reading the associated programs from the registry – Fender Jul 13 '11 at 13:10
  • 1
    Look here. You must get the info from registry http://stackoverflow.com/questions/212906/script-to-associate-an-extension-to-a-program#212921 – Orhan Cinar Jul 13 '11 at 13:11
  • 1
    possible duplicate of [Windows: List and Launch applications associated with an extension](http://stackoverflow.com/questions/24954/windows-list-and-launch-applications-associated-with-an-extension) – Hans Passant Jul 13 '11 at 13:17
  • @Oded: firstly i look into registry, but there only program that runs when user double-clicks on a file, my goal to list alternative programs from "Open With..." dialog box or same drop down menu – Alexander Jul 14 '11 at 01:41
  • @Hans Passant: that question is about get "primary" association, i need to get recommended associations – Alexander Jul 14 '11 at 01:54

3 Answers3

14

I wrote a small routine:

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;
  }

which gets called like so:

foreach (string prog in RecommendedPrograms("vb"))
{
  MessageBox.Show(prog);
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • 1
    thanks for taking time for writing this routine, but it seems that it's very tangled way to get those kind of things from registry... for example about xls extension: routine returns not only recommended programs, but all apllications that ever opened this type of file (even applications written by me), also it returns only one progrId Excel.Sheet.8, i've tried to serach registry for it but found only path to office 11 excel... Anyway thanks again for providing good answer. it's more than nothing – Alexander Jul 22 '11 at 02:34
  • Not bad, but doesn't get you the program names :/ – StinkyCat Nov 14 '13 at 18:42
3

Ever wanted to programmatically associate a file type on the system with your application, but didn't like the idea of digging through the registry yourself? If so, then this article and code are right for you.

System File Association

Orhan Cinar
  • 8,403
  • 2
  • 34
  • 48
  • thanks for help, but i ned to get associations, not to set) i look into source code but still can't find a way( – Alexander Jul 14 '11 at 02:37
0

I improved method by LarsTech. Now it returns paths to programs.

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;
}
NeoSvet
  • 151
  • 1
  • 4