【问题标题】:How to obtain the path to the directory of the frontmost Windows Explorer window using Python?如何使用 Python 获取最前面的 Windows 资源管理器窗口的目录路径?
【发布时间】:2021-05-14 23:47:48
【问题描述】:

我的问题是我正在制作一个程序,该程序将根据用户作为文件资源管理器打开的文件夹获取文件数据......我已经浏览了整个互联网以找到答案,但似乎这个问题从来没有人面对过。许多答案与项目文件所在的当前工作目录有关。

所以,我基本上想要用户当前在文件资源管理器中查看的文件夹的路径...

【问题讨论】:

  • 什么是文件浏览器?您的意思是所有这些都包括终端文件浏览器,如游侠或一个特定的文件浏览器?如果用户使用一个文件资源管理器的 5 个实例打开 5 个不同的文件夹怎么办?
  • @ThomasSablik 可能是一个 文件浏览器 内置的 Windows 我想,这是我唯一能想到的同名。
  • @jupiterbjy 在问题中看不到 Windows。
  • 一个特定的,普通用户每天都在使用它......就像Windows中的我的电脑。我想要用户当前在我的电脑中所在的文件夹的路径。例如 (D:\Games)
  • 这能回答你的问题吗? Obtain Active window using Python

标签: python python-3.x windows explorer


【解决方案1】:
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:
    try:
        explorer_fileselection()
    except Exception:
        print("No Path Found!")
    time.sleep(1)

嗯,我的解决方案相当复杂,但我已经为你找到了这个。希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我能想到的最好方法是编写 Python 软件以在资源管理器中使用上下文菜单。通过快速谷歌搜索,我找到了一个有趣的库:https://pypi.org/project/context-menu/

    我想没有明智的方法可以从另一个进程中读取数据。这会导致安全问题。

    【讨论】:

    • “我想没有明智的方法从另一个进程读取数据。那会导致安全问题。”它被称为API。许多程序为这种通信提供接口:docs.microsoft.com/en-us/windows/win32/shell/…
    • @ThomasSablik:谢谢你的信息。我不知道 Windows Explorer 提供 API。我正在考虑尝试从不提供 API 或 API 不提供的数据的进程中读取数据的场景。例如,我希望没有人可以从我的 banksoftware.exe 进程中读取数据。
    • 在 Windows 上可以。这就是大多数游戏作弊软件的工作方式。他们读取游戏过程的记忆并尝试解释这些值以在以后更改它们。在其他操作系统上,这很难或不可能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 2017-07-07
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多