Python - Get Path of Selected File in Current Windows Explorer -


i trying this in python 2.7. have found answer in c# here, having trouble recreating in python. answer suggested here explain concept understand, have no idea how going.

basically want mark file, press winkey+c , have path copied. know how hotkey part (pyhk, win32 [registerhotkey]), trouble working around filepath.

thanks in advance!

it takes lot of hacking around, rough solution below:

#!python3 import win32gui, time win32con import page_readwrite, mem_commit, mem_reserve, mem_release, process_all_access, wm_gettextlength, wm_gettext commctrl import lvm_getitemtext, lvm_getitemcount, lvm_getnextitem, lvni_selected import os import struct import ctypes import win32api  getwindowthreadprocessid = ctypes.windll.user32.getwindowthreadprocessid virtualallocex = ctypes.windll.kernel32.virtualallocex virtualfreeex = ctypes.windll.kernel32.virtualfreeex openprocess = ctypes.windll.kernel32.openprocess writeprocessmemory = ctypes.windll.kernel32.writeprocessmemory readprocessmemory = ctypes.windll.kernel32.readprocessmemory memcpy = ctypes.cdll.msvcrt.memcpy  def readlistviewitems(hwnd, column_index=0):      # allocate virtual memory inside target process     pid = ctypes.create_string_buffer(4)     p_pid = ctypes.addressof(pid)     getwindowthreadprocessid(hwnd, p_pid) # process owning given hwnd     hprochnd = openprocess(process_all_access, false, struct.unpack("i",pid)[0])     plvi = virtualallocex(hprochnd, 0, 4096, mem_reserve|mem_commit, page_readwrite)     pbuffer = virtualallocex(hprochnd, 0, 4096, mem_reserve|mem_commit, page_readwrite)      # prepare lvitem record , write target process memory     lvitem_str = struct.pack('iiiiiiiii', *[0,0,column_index,0,0,pbuffer,4096,0,0])     lvitem_buffer = ctypes.create_string_buffer(lvitem_str)     copied = ctypes.create_string_buffer(4)     p_copied = ctypes.addressof(copied)     writeprocessmemory(hprochnd, plvi, ctypes.addressof(lvitem_buffer), ctypes.sizeof(lvitem_buffer), p_copied)      # iterate items in syslistview32 control     num_items = win32gui.sendmessage(hwnd, lvm_getitemcount)     item_texts = []     item_index in range(num_items):         win32gui.sendmessage(hwnd, lvm_getitemtext, item_index, plvi)         target_buff = ctypes.create_string_buffer(4096)         readprocessmemory(hprochnd, pbuffer, ctypes.addressof(target_buff), 4096, p_copied)         item_texts.append(target_buff.value)      virtualfreeex(hprochnd, pbuffer, 0, mem_release)     virtualfreeex(hprochnd, plvi, 0, mem_release)     win32api.closehandle(hprochnd)     return item_texts  def getselectedlistviewitem(hwnd):     return win32gui.sendmessage(hwnd, lvm_getnextitem, -1, lvni_selected)  def getedittext(hwnd): #   buf_size = 1 + win32gui.sendmessage(hwnd, wm_gettextlength, 0, 0) #   print(buf_size) #   buffer = ' ' * buf_size #   print(win32gui.sendmessage(hwnd, wm_gettext, buf_size, buffer)) #   return buffer[:buf_size]  #def getedittext2(hwnd):     # api returns 16 bit characters buffer needs 1 more char null , twice 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 null char on end  def _normalisetext(controltext):     '''remove '&' characters, , lower case.     useful matching control text.'''     return controltext.lower().replace('&', '')  def _windowenumerationhandler(hwnd, resultlist):     '''pass win32gui.enumwindows() 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:         # seems mean control *cannot* have child windows,         # i.e. not container.         return     childhwnd, windowtext, windowclass in childwindows:         descendentmatchinghwnds = searchchildwindows(childhwnd)         if descendentmatchinghwnds:             results += descendentmatchinghwnds          if wantedtext , \             not _normalisetext(wantedtext) in _normalisetext(windowtext):                 continue         if wantedclass , \             not windowclass == wantedclass:                 continue         if selectionfunction , \             not selectionfunction(childhwnd):                 continue         results.append(childhwnd)     return results  w=win32gui  while true:     time.sleep(5)     window = w.getforegroundwindow()     print("window: %s" % window)     if (window != 0):         if (w.getclassname(window) == 'cabinetwclass'): # 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             child in children:                 if (w.getclassname(child) == 'comboboxex32'): # address bar                     addr_children = list(set(searchchildwindows(child)))                     addr_child in addr_children:                         if (w.getclassname(addr_child) == 'edit'):                             addr_edit = addr_child                     pass                 elif (w.getclassname(child) == 'syslistview32'): # list control within window shows files                     file_view = child             if addr_edit:                 path = getedittext(addr_edit)             else:                 print('something went wrong - no address bar found')                 path = ''              if file_view:                 files = [item.decode('utf8') item in readlistviewitems(file_view)]                 index = getselectedlistviewitem(file_view)                 selected_file = files[index]                 print('files: %s' % files)                 print('selected file: %s' % selected_file)                 print('path: %s' % path)                 print('file path: %s' % os.path.join(path, selected_file))             else:                 print('something went wrong - no file view found') 

so keep checking if active window of class explorer window uses, iterates through children widgets find address bar , file list view. when extracts list of files listvies , requests selected index. gets , decodes text address bar.
@ bottom info combined give complete path, folder path, file name or combination thereof.

i have tested on windows xp python3.4, need install win32gui , win32 conn packages.


Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -