Я знаю, что сейчас "немного" поздно публиковать здесь ответ, но я попробовал решение Олава несколько месяцев назад, и оно не сработало полностью: рабочий каталог был рабочим каталогом сценария, поэтому мне пришлось удалить условие if для он работал, но он выбрал все файлы во всех окнах проводника Windows (что я тоже хотел, так что это сработало частично для меня). Но теперь я вернулся, чтобы продолжить свой проект (помощник), и я обнаружил, что мне действительно нужна эта работа, поэтому я подумал над этой идеей (которую не так уж сложно придумать, но мне потребовались месяцы, чтобы она появилась ... ). Я не знаю, сработал ли этот ответ для кого-то еще, но для меня это не было полностью, поэтому я подумал, что могу улучшить его и опубликовать свое решение здесь. Этот код представляет собой смесь этого ответа (который я тоже использовал в том же скрипте, но никогда не думал о том, чтобы заставить их работать вместе): https://stackoverflow.com/a/43892579/8228163 (исправлено мной, чтобы работать как минимум под Windows 7), и ответ Олава и результат сработали для меня - скрипт обнаруживает файлы только в текущем Окно проводника Windows. Я думаю, что все это работает от Vista (может быть, я не знаю, она старше 7) до 10, но я не совсем уверен. Другой ответ - работать с XP. Когда я запускал этот скрипт в Windows 10, я думал, что он сработал, но у меня больше нет 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, получает адрес этого окна, а затем адрес используется в ответе Олафа, чтобы проверить, совпадает ли этот адрес с одним из адресов, открытых в проводнике Windows, получая файлы из активного окна. Кстати, поскольку это скрипт является измененной копией обоих ответов, он имеет ограничения от них. Итак, как и в ответе Олафа «Изменить: еще не работает, по крайней мере, при использовании контекстного меню», то это, вероятно, тоже не сработает, поскольку это тот же код - это просто рабочий каталог, который отличается (хотя, Я не знаю, что он имел в виду, но для того, что я тестировал, это сработало). И, как и в ответе Джеймса Кента, это не работает для рабочего стола, только для открытых окон с помощью проводника Windows. Кодировка = 'ISO 8859-1' связана с тем, что я португальский, но ее можно изменить, ПРОСТО убедитесь, что оба каталога равны без%? S, иначе это не сработает!
Поскольку на этот вопрос всего почти 5 лет, OP, вероятно, он больше не понадобится, но он мне был нужен, и его нигде не было, поэтому я подумал, что могу опубликовать это здесь и, возможно, помочь другим, кто хочет это сделать. Код в сценарии можно использовать для определения файлов в текущем окне проводника Windows и для получения текущего пути к окну проводника Windows в Windows выше XP (не уверен в Vista). Для XP см. Исходный ответ (https://stackoverflow.com/a/43892579/8228163) и получить файлы из всех окон проводника Windows, просто удалите условие if из ответа Олафа.
Спасибо Олаву и Джеймсу Кенту за ответы, потому что я бы потратил НАМНОГО больше времени, пытаясь выяснить, как это сделать (я начинаю с Python / любого языка - просто кодирую в течение года, так что это заняло бы действительно много времени , может, придется перепутать с другим языком). Еще раз спасибо, а также OP за то, что задали вопросы и получили ответы от нужных людей в нужное время! (поскольку источник, который процитировал Олав по ссылке, больше не существует).
Надеюсь это поможет! Ваше здоровье!
person
DADi590
schedule
24.10.2018