我知道现在在这里发布答案有点晚了,但我几个月前尝试过Olav的解决方案,但它没有完全起作用:工作目录是脚本的工作目录,所以我不得不删除if条件才能使其工作,但它选择了所有Windows资源管理器窗口中的所有文件(我也希望这样做,所以这部分对我有效)。但现在我回来继续我的项目(一个助理),我发现我真的需要这个工作,所以我考虑这个想法(这不是很难想到,但我花了几个月的时间…)。我不知道这个答案是否对其他人有用,但对我来说,它并不完全有效,所以我想我可以改进它,并在这里发布我的解决方案。这段代码是这个答案的混合体(我在同一个脚本中也使用过,但从未想过让它们一起工作):/a/43892579/8228163(至少在Windows7下可以工作)和Olav的答案以及对我有用的结果——脚本只在当前的Windows资源管理器窗口中检测文件。我想从Vista(也许,我不知道它的年龄超过7岁)到10岁,但我不完全确定。另一个答案是使用XP。当我在Windows10上启动这个脚本时,我认为它是有效的,但是我已经没有10个了,所以我不能确定(我又用了7,所以对于7来说这是有效的)。在import win32gui, time
from win32con import PAGE_READWRITE, MEM_COMMIT, MEM_RESERVE, MEM_RELEASE, PROCESS_ALL_ACCESS, WM_GETTEXTLENGTH, WM_GETTEXT
from commctrl import LVS_OWNERDATA, LVM_GETITEMCOUNT, LVM_GETNEXTITEM, LVNI_SELECTED
import os
import struct
import ctypes
import win32api
import datetime
import win32com.client as win32
import win32ui
import psutil
import subprocess
import time
import urllib.parse
clsid = '{9BA05972-F6A8-11CF-A442-00A0C90A8F39}' #Valid for IE as well!
def getEditText(hwnd):
# api returns 16 bit characters so buffer needs 1 more char for null and twice the num of chars
buf_size = (win32gui.SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0) +1 ) * 2
target_buff = ctypes.create_string_buffer(buf_size)
win32gui.SendMessage(hwnd, WM_GETTEXT, buf_size, ctypes.addressof(target_buff))
return target_buff.raw.decode('utf16')[:-1]# remove the null char on the end
def _normaliseText(controlText):
'''Remove '&' characters, and lower case.
Useful for matching control text.'''
return controlText.lower().replace('&', '')
def _windowEnumerationHandler(hwnd, resultList):
'''Pass to win32gui.EnumWindows() to generate list of window handle,
window text, window class tuples.'''
resultList.append((hwnd, win32gui.GetWindowText(hwnd), win32gui.GetClassName(hwnd)))
def searchChildWindows(currentHwnd,
wantedText=None,
wantedClass=None,
selectionFunction=None):
results = []
childWindows = []
try:
win32gui.EnumChildWindows(currentHwnd,
_windowEnumerationHandler,
childWindows)
except win32gui.error:
# This seems to mean that the control *cannot* have child windows,
# i.e. not a container.
return
for childHwnd, windowText, windowClass in childWindows:
descendentMatchingHwnds = searchChildWindows(childHwnd)
if descendentMatchingHwnds:
results += descendentMatchingHwnds
if wantedText and \
not _normaliseText(wantedText) in _normaliseText(windowText):
continue
if wantedClass and \
not windowClass == wantedClass:
continue
if selectionFunction and \
not selectionFunction(childHwnd):
continue
results.append(childHwnd)
return results
def explorer_fileselection():
global clsid
address_1=""
files = []
shellwindows = win32.Dispatch(clsid)
w=win32gui
window = w.GetForegroundWindow()
#print("window: %s" % window)
if (window != 0):
if (w.GetClassName(window) == 'CabinetWClass'): # the main explorer window
#print("class: %s" % w.GetClassName(window))
#print("text: %s " %w.GetWindowText(window))
children = list(set(searchChildWindows(window)))
addr_edit = None
file_view = None
for child in children:
if (w.GetClassName(child) == 'WorkerW'): # the address bar
addr_children = list(set(searchChildWindows(child)))
for addr_child in addr_children:
if (w.GetClassName(addr_child) == 'ReBarWindow32'):
addr_edit = addr_child
addr_children = list(set(searchChildWindows(child)))
for addr_child in addr_children:
if (w.GetClassName(addr_child) == 'Address Band Root'):
addr_edit = addr_child
addr_children = list(set(searchChildWindows(child)))
for addr_child in addr_children:
if (w.GetClassName(addr_child) == 'msctls_progress32'):
addr_edit = addr_child
addr_children = list(set(searchChildWindows(child)))
for addr_child in addr_children:
if (w.GetClassName(addr_child) == 'Breadcrumb Parent'):
addr_edit = addr_child
addr_children = list(set(searchChildWindows(child)))
for addr_child in addr_children:
if (w.GetClassName(addr_child) == 'ToolbarWindow32'):
text=getEditText(addr_child)
if "\\" in text:
address_1=getEditText(addr_child)[text.index(" ")+1:]
print("Address --> "+address_1)
for window in range(shellwindows.Count):
window_URL = urllib.parse.unquote(shellwindows[window].LocationURL,encoding='ISO 8859-1')
window_dir = window_URL.split("///")[1].replace("/", "\\")
print("Directory --> "+window_dir)
if window_dir==address_1:
selected_files = shellwindows[window].Document.SelectedItems()
for file in range(selected_files.Count):
files.append(selected_files.Item(file).Path)
print("Files --> "+str(files))
while True:
explorer_fileselection()
time.sleep(1)
这将查找活动的Windows资源管理器窗口,获取该窗口的地址,然后将该地址用于Olav的答案,以检查该地址是否等于在Windows资源管理器中打开的地址之一,从而从活动窗口获取文件。顺便说一句,因为这个脚本是两个答案的修改副本,所以它有来自这些答案的限制。所以,就像Olav的回答“编辑:还不起作用,至少在使用上下文菜单时是这样的”,那么这可能也不起作用,因为它是相同的代码-只是工作目录不同(虽然,我不知道他说的是什么意思,但就我测试的结果来看,它起作用了)。就像jameskent的答案一样,这不适用于桌面,只适用于使用windows资源管理器打开的窗口。
编码=“ISO 8859-1”是因为我是葡萄牙语,但可以更改,只需确保两个目录都相等而不必使用%?否则就没用了!在
因为这个问题只有近5年的时间,OP可能不再需要它了,但我需要它,却没有它在任何地方,所以我想我可以把这个贴在这里,也许可以帮助其他想这样做的人。脚本中的代码可用于了解当前Windows资源管理器窗口上的文件,并在XP以上的Windows上获取当前的Windows资源管理器窗口路径(对Vista不确定)。对于XP,请参阅原始答案(/a/43892579/8228163),要从所有Windows资源管理器窗口获取文件,只需从Olav的答案中删除if条件。在
感谢Olav和James Kent给出的答案,因为我会花更多的时间来尝试如何做到这一点(我是一个Python/任何语言begginner—只需编写一年代码,所以需要花费大量时间,也许我必须将其与另一个语言混合使用)。再次感谢你们,感谢你们的行动,感谢你们在正确的时间问了问题,让合适的人来回答!(因为Olav在链接上引用的源不再存在)。在
希望这有帮助!干杯!在