def find_programs(extensions): extensions = frozenset(extensions) ans = [] seen_prog_ids, seen_cmdlines = set(), set() # Search for programs registered using Default Programs that claim they are # capable of handling the specified extensions. for base in (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE): try: k = Key(open_at=r'Software\RegisteredApplications', root=base) except WindowsError as err: if err.errno == winerror.ERROR_FILE_NOT_FOUND: continue raise with k: for name, key_path in k.values(get_data=True): try: app_desc, prog_id_map = get_prog_id_map(base, key_path) except Exception: import traceback traceback.print_exc() continue for ext in extensions: prog_id = prog_id_map.get(ext) if prog_id is not None and prog_id not in seen_prog_ids: seen_prog_ids.add(prog_id) cmdline, icon_resource, friendly_name = get_open_data(base, prog_id) if cmdline and cmdline not in seen_cmdlines: seen_cmdlines.add(cmdline) ans.append({'name':app_desc, 'cmdline':cmdline, 'icon_resource':icon_resource}) # Now look for programs that only register with Windows Explorer instead of # Default Programs (for example, FoxIt PDF reader) for ext in extensions: try: k = Key(open_at=r'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.%s\OpenWithProgIDs' % ext, root=HKEY_CURRENT_USER) except WindowsError as err: if err.errno == winerror.ERROR_FILE_NOT_FOUND: continue for prog_id in itervalues(k): if prog_id and prog_id not in seen_prog_ids: seen_prog_ids.add(prog_id) cmdline, icon_resource, friendly_name = get_open_data(base, prog_id) if cmdline and cmdline not in seen_cmdlines: seen_cmdlines.add(cmdline) exe_name = None exe = split_commandline(cmdline) if exe: exe_name = friendly_app_name(prog_id) or os.path.splitext(os.path.basename(exe[0]))[0] name = exe_name or friendly_name if name: ans.append({'name':name, 'cmdline':cmdline, 'icon_resource':icon_resource}) return ans
def get_prog_id_map(base, key_path): desc, ans = None, {} try: k = Key(open_at=key_path, root=base) except WindowsError as err: if err.errno == winerror.ERROR_FILE_NOT_FOUND: return desc, ans raise with k: desc = k.get_mui_string('ApplicationDescription') if desc is None: return desc, ans for ext, prog_id in k.values(sub_key='FileAssociations', get_data=True): ans[ext[1:].lower()] = prog_id return desc, ans