2017-05-13 10 views
0

私は現在、Win32 APIを使用してPython 3を使用しています。ウィンドウの検査のために、Microsoft Inspect Toolを使用しています。pywin32で選択したエクスプローラウィンドウからすべてのファイルのリストを返します。

def getSelectedFile(): 

    def callback(handle, hwnds): 
     print(str(handle) + " - class name: " + win32gui.GetClassName(handle) + "-- name: " + win32gui.GetWindowText(handle)) 
     return True 

    hwnd = win32gui.GetForegroundWindow() 
    if hwnd: 
     if win32gui.GetClassName(hwnd) == 'CabinetWClass': # this is the main explorer window 
      win32gui.EnumChildWindows(hwnd, callback, None) 

そして、これは、出力を次のようになります:

19269320 - class name: BrowserFrameGripperClass-- name: 
526990 - class name: WorkerW-- name: 
395922 - class name: ReBarWindow32-- name: 
13371224 - class name: TravelBand-- name: 
2559382 - class name: ToolbarWindow32-- name: 
11076870 - class name: Address Band Root-- name: 
2230638 - class name: msctls_progress32-- name: 
7930970 - class name: Breadcrumb Parent-- name: 
6292500 - class name: ToolbarWindow32-- name: Address: Libraries\Pictures 
8980342 - class name: ToolbarWindow32-- name: 
9568934 - class name: UniversalSearchBand-- name: 
11403790 - class name: Search Box-- name: 
7407762 - class name: SearchEditBoxWrapperClass-- name: 
23266054 - class name: DirectUIHWND-- name: 
7078564 - class name: ShellTabWindowClass-- name: Pictures 
11732514 - class name: DUIViewWndClassName-- name: 
12584158 - class name: DirectUIHWND-- name: 
1118546 - class name: CtrlNotifySink-- name: 
987636 - class name: NamespaceTreeControl-- name: Namespace Tree Control 
8193258 - class name: Static-- name: Namespace Tree Control 
24314574 - class name: SysTreeView32-- name: Tree View 
21103510 - class name: CtrlNotifySink-- name: 
1642968 - class name: Shell Preview Extension Host-- name: Shell Preview Extension Host 
1577368 - class name: CtrlNotifySink-- name: 
2036036 - class name: SHELLDLL_DefView-- name: ShellView 
24380214 - class name: DirectUIHWND-- name: 
1969552 - class name: CtrlNotifySink-- name: 
594366 - class name: ScrollBar-- name: 
987466 - class name: CtrlNotifySink-- name: 
17827752 - class name: ScrollBar-- name: 
2035978 - class name: CtrlNotifySink-- name: 
4851916 - class name: Button-- name: Save 
13174848 - class name: CtrlNotifySink-- name: 
7145486 - class name: Button-- name: Cancel 
1509810 - class name: WorkerW-- name: 
12781114 - class name: ReBarWindow32-- name: 
11405468 - class name: ToolbarWindow32-- name: 
1315080 - class name: msctls_statusbar32-- name: 

素晴らしいですが、どの現在、私はすべての窓から列挙し、次のコードを持っています。しかし、これらのオブジェクトには、検査ツールを見ることによってフレームワークIDのみが「Win32」であることにも注意してください(図のように)。インスペクタから

enter image description here

、私はいくつかのオブジェクトは、「DirectUI」という名前の異なるframeworkIdを持っていることに気づいた、と彼らはEnumChildWindows関数から現れていないようです。これは問題です。すべてのファイルを含むオブジェクトは実際には「アイテムビュー」ペインと呼ばれ、「DirectUI」です(2番目の図を参照)。だから、それは検出されていない。それが検出されない場合は、その中のすべてのファイルをどのように読み取ることができますか?私はあなたが

enter image description here

は、どのように私はWin32APIのは、ファイル名を読み取るためにDirectUIで動作するように取得することができます(下の写真の)ツリーでそれらを見ることができるので、名前があることを知っていますか?
すべてのファイルの名前のリストを取得する簡単な方法はありますか?

+1

。 [IFolderViewインターフェイス](https://msdn.microsoft.com/de-de/library/windows/desktop/bb775606(v = vs.85).aspx)のインスタンスを取得したら、IFolderView: :Item() 'メソッドを使ってファイル/フォルダのリストを読み込みます。以下は、[エクスプローラウィンドウからIFolderViewインターフェイスを取得するためのC++コード](http://stackoverflow.com/a/43821628/7571258)です。これをPythonコードに翻訳する必要があります。以下は、[シェルオブジェクトを使い始めるためのPythonコード](http://stackoverflow.com/a/21250927/7571258)です。 – zett42

+2

実装の詳細に依存しています。しないでください。 APIを使用します。 –

+0

@DavidHeffernanあなたはどこでPythonのWindowsシェルを学び始めるべきですか?推奨できるリソース/サイトはありますか?ありがとう。 – Dragneel

答えて

1

シェルには、pywin32からアクセスできるこのようなもののためのdedicated COM APIがあります。 (私は実際にはC++男だとして)

import os 
import sys 
import win32con 
import win32api 
import win32gui 
import win32com.client 
import pythoncom 
from win32com.shell import shell, shellcon 

# Get list of paths from given Explorer window or from all Explorer windows. 
def get_explorer_files(hwndOfExplorer = 0, selectedOnly = False): 
    paths = [] 

    # Create instance of IShellWindows (I couldn't find a constant in pywin32) 
    CLSID_IShellWindows = "{9BA05972-F6A8-11CF-A442-00A0C90A8F39}" 
    shellwindows = win32com.client.Dispatch(CLSID_IShellWindows) 

    # Loop over all currently open Explorer windows 
    for window in shellwindows: 
     # Skip windows we are not interested in. 
     if hwndOfExplorer != 0 and hwndOfExplorer != window.HWnd: 
      continue 

     # Get IServiceProvider interface 
     sp = window._oleobj_.QueryInterface(pythoncom.IID_IServiceProvider) 

     # Query the IServiceProvider for IShellBrowser 
     shBrowser = sp.QueryService(shell.SID_STopLevelBrowser, shell.IID_IShellBrowser) 

     # Get the active IShellView object 
     shView = shBrowser.QueryActiveShellView() 

     # Get an IDataObject that contains the items of the view (either only selected or all). 
     aspect = shellcon.SVGIO_SELECTION if selectedOnly else shellcon.SVGIO_ALLVIEW 
     items = shView.GetItemObject(aspect, pythoncom.IID_IDataObject) 

     # Get the paths in drag-n-drop clipboard format. We don't actually use 
     # the clipboard, but this format makes it easy to extract the file paths. 
     # Use CFSTR_SHELLIDLIST instead of CF_HDROP if you want to get ITEMIDLIST 
     # (aka PIDL) format, but you can't use the simple DragQueryFileW() API then. 
     data = items.GetData((win32con.CF_HDROP, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL)) 

     # Use drag-n-drop API to extract the individual paths. 
     numPaths = shell.DragQueryFileW(data.data_handle, -1) 
     paths.extend([ 
      shell.DragQueryFileW(data.data_handle, i) \ 
       for i in range(numPaths) 
     ]) 

     if hwndOfExplorer != 0: 
      break 

    return paths 

try: 
    # Use hwnd value of 0 to list files of ALL explorer windows... 
    hwnd = 0 
    # ... or restrict to given window: 
    #hwnd = win32gui.GetForegroundWindow() 
    selectedOnly = False 
    print(*get_explorer_files(hwnd, selectedOnly), sep="\n") 
except Exception as e: 
    print("ERROR: ", e) 

うわーが、それは素敵なパズルだった:

ここで働いているコードは、私が作ってみました!

私がoriginal MSDN documentationを勉強することを示唆するものを理解するには、それをpywin32 codeにマップしてみてください。

シェルAPI(と一般的にCOM)は、最初は少し圧倒されることがありますが、通常、既存のサンプルコードを適用することはそれほど難しくありません。そのための素晴らしい情報源はblog of Raymond Chenです。

はpywin32サンプルについては、pywin32インストールのこのフォルダにいくつかのデモがあります。私は窓の周りいじるのではなく、シェルのCOM APIを使用することをお勧め

Lib\site-packages\win32comext\shell\demos\ 
関連する問題