笔者最近购买了一台Windows 11 电脑, 安装了Windows更新后, 发现资源管理器的文件搜索框不能打字。是不是系统内置的搜索功能损坏了?
其实没有, 只是系统界面出了问题。真正的搜索功能仍然可以通过Python用search-ms
链接调用。
调用系统搜索功能
search-ms是搜索框中输入文字时, 在资源管理器地址栏中出现的链接。search-ms链接的构成如下:
search-ms:displayname=窗口标题&crumb=&crumb=System.Generic.String:搜索词&crumb=location:搜索位置(即范围)
使用Python在资源管理器打开search-ms链接
经笔者测试, 无法直接调用explorer.exe
命令打开, 而需要调用start
命令。
import os
# 因为os.system会将&符号解释为多条命令, 所以需要^将&符号转义
os.system("start search-ms:displayname=My_Result&crumb=&crumb=System.Generic.String:pyc&crumb=location:E%3A%5CPython"\
.replace('&','^&'))
要将参数加入链接, 需要使用urllib.parse
模块中的quote()
函数将其转换。如: quote("E:\Python")
得到的是E%3A%5CPython"
。
import os
from urllib.parse import quote
keyword="pyc"
path = "E:\\Python"
url = "start search-ms:displayname=My_Result&crumb=&crumb=System.Generic.String:%s&crumb=location:%s" % (quote(keyword),quote(path))
os.system(url.replace('&','^&'))
设计tkinter界面及程序
该tkinter界面使用窗体对象.overrideredirect(True)
方法去除窗口的边框, 使用tk-dragtool
库使窗口可以被拖动。程序使用windnd
库实现将文件夹拖入窗口中。
最终的程序如下:
import os
from urllib.parse import quote_from_bytes as _quote
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.font import Font
from tk_dragtool import bind_drag
import tkinter.messagebox as msgbox
import windnd
_safe = '''ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789_.-~'''
# 重写quote方法, 使支持中文
# 已知: 系统不能识别已被quote的中文
def quote(string):
result = ''
for c in string:# _safe中的字符, 和非ASCII字符可以保留在url中
if ord(c) < 128 and c not in _safe:
result+=_quote(c.encode())
else:
result+=c
return result
path=None
def ondrag(filenames):
global path
if len(filenames)!=1 or not \
os.path.isdir(filenames[0].decode("ansi")):
msgbox.showinfo("","只允许拖曳一个文件夹")
path = filenames[0].decode("ansi")
tip["text"]="当前搜索范围: "+path
def launch_search():
if path is None:
msgbox.showinfo("","您还没有选择搜索范围!")
return
word = kw.get()
title = path + "的Python调用搜索结果"
url = 'search-ms:displayname=%s&crumb=&crumb=System.Generic.String:%s&crumb=location:%s'%(
quote(title), quote(word), quote(path))
print(url)
# cmd命令中, ^将&符号转义
os.system('start '+url.replace('&','^&'))
root=tk.Tk()
root.title("Windows 搜索框模拟")
root.geometry("400x60")
#root.overrideredirect(True) 去除窗口的边框
tip=tk.Label(root,text="拖曳搜索范围的文件夹到此: ")
tip.pack(side=tk.TOP,fill=tk.X)
bind_drag(root,tip) # 使用tk-dragtool库绑定拖曳
kw=ttk.Entry(root,font=("Microsoft Yahei",12,"normal"))
kw.pack(side=tk.LEFT,expand=True,fill=tk.BOTH)
btn=ttk.Button(root,text="搜索",command=launch_search,width=6)
btn.pack(side=tk.RIGHT,fill=tk.Y)
windnd.hook_dropfiles(root,func=ondrag) # 绑定文件夹拖入事件
root.mainloop()
运行效果: