今天闲得蛋疼清理了一下右键菜单,于是在之后某时刻使用Everything的“双击路径列打开目录”功能时发现异常:
[Window Title] Everything.exe [Content] 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联。 [确定]
接下来的自救过程实在曲折,中间查到Everything是调用Windows API SHOpenFolderAndSelectItems 失败导致弹这个错误(Automatically open folder again with "Open path with double click")。
我甚至还在网上找了一份可以调用这个API的代码,运行这份测试代码时出现了几乎完全一样的错误窗口。
1 #!python3 2 # https://stackoverflow.com/questions/20565401/how-to-access-shopenfolderandselectitems-by-ctypes 3 4 import win32api 5 from win32com.shell import shell, shellcon 6 import os 7 8 def launch_file_explorer(path, files): 9 ''' 10 Given a absolute base path and names of its children (no path), open 11 up one File Explorer window with all the child files selected 12 ''' 13 folder_pidl = shell.SHILCreateFromPath(path,0)[0] 14 desktop = shell.SHGetDesktopFolder() 15 shell_folder = desktop.BindToObject(folder_pidl, None,shell.IID_IShellFolder) 16 name_to_item_mapping = dict([(desktop.GetDisplayNameOf(item, shellcon.SHGDN_FORPARSING|shellcon.SHGDN_INFOLDER), item) for item in shell_folder]) 17 print("name_to_item_mapping: {0}".format(name_to_item_mapping)) 18 to_show = [] 19 for file in files: 20 if file in name_to_item_mapping: 21 to_show.append(name_to_item_mapping[file]) 22 else: 23 raise Exception('File: "%s" not found in "%s"' % (file, path)) 24 25 print("to_show: {0}".format(to_show)) 26 print("call SHOpenFolderAndSelectItems()") 27 result = shell.SHOpenFolderAndSelectItems(folder_pidl, to_show, 0) 28 last_error = win32api.GetLastError() 29 print("SHOpenFolderAndSelectItems returned {0}".format(result)) 30 31 p=r'Z:\SHARE' 32 print(os.listdir(p)) 33 launch_file_explorer(p, os.listdir(p))
此时其实离最终答案已经不远了,可我却没有及时发现,折腾到后期甚至怀疑并不是注册表引起的问题,毕竟早已经尝试过把右键菜单还原回去了。
直至尝试系统还原并且失败后,五味杂陈地一边看着这个窗口一边备份文件时才忽然灵光乍现!
既然可能是操作注册表导致的故障,那么找一份OK的注册表来对比或许还有救。
于是从另一台正常的Windows 10 PC里导出 HKEY_CLASSES_ROOT\Folder ,跟这里故障机导出的文件对比:
把天杀的 none 删除后故障成功排除!
此时回想起出问题的API SHOpenFolderAndSelectItems 名字里带着 Folder ,真是蓝瘦……