2013-06-21 25 views
5

Czy istnieje skuteczny sposób przy użyciu dowolnego modułu Pythona jak PyWind32 współdziałać z już istniejących oknach dialogowych Native OS jak pudełka „Zapisz jako”?Jaki jest najlepszy sposób interakcji z już otwartymi rodzimymi oknami dialogowymi systemu operacyjnego, takimi jak (Save AS) przy użyciu Pythona?

Próbowałem wyszukiwanie w Google, ale bez pomocy.

EDIT:

1: W oknie dialogowym Zapisz jako jest wyzwalany, gdy użytkownik kliknie na oknie dialogowym Zapisz w aplikacji internetowej As.

. 2: Wszelkie sugestie są mile widziane, aby obsługiwać żadnych rodzimych okien dialogowych systemu operacyjnego, które są już uruchamiane przy użyciu Python (nie muszą być specyficzne dla Selen webdriver, szukam rodzajowe sugestią.)

(Kiedy byłem umieszczając pytanie, które myślałem, że "wchodząc w interakcję z oknem dialogowym" domyślnie oznacza, że ​​jest on istniejący tak, jakbym był w stanie go stworzyć, to na pewno mogę z nim współdziałać, ponieważ jest on pod kontrolą moich programów. 2 odpowiedzi zdałem sobie sprawę, że nie było wyraźnie jasne. to dlatego EDIT)

Dzięki

+0

Jakie są interakcji próbujesz to zrobić? –

+0

@DavidHeffernan Mam aplikację internetową z wyzwalaczami nowe okno Zapisz jako okno dialogowe.Potrzebuję interakcji w tym sensie, że muszę kliknąć na różne opcje obecne w oknie dialogowym i wprowadzić ścieżkę docelową oraz nazwę pliku do zapisania. – abhi

+0

Dlaczego downvote – abhi

Odpowiedz

5

Szukając możliwego rozwiązania, natknąłem się na kilka rozwiązań na SO i nie tylko. Niektórzy używali AutoIT lub przeglądarek edycji profilu, aby zapisać plik bezpośrednio bez wierszu.

znalazłem wszystko to rozwiązanie zbyt szczegółowe jak można przezwyciężyć ten problem na oknie dialogowym Zapisz jako edytując profil przeglądarki, ale jeśli później trzeba obsłużyć jakieś inne okno następnie utkniesz. Do korzystania AutoIT jest przesadą, to zderza się bezpośrednio na fakt wybiorę Python aby wykonać to zadanie. (Mam na myśli, że Python sam jest tak potężny, w zależności od jakiegoś innego narzędzia jest BEZPIECZNY dla jakiegokolwiek Pythonist)

Po długim poszukiwaniu możliwego rozwiązania tego problemu, które nie tylko służy każdemu, kto chce sobie poradzić dowolne okna dialogowe systemu Native OS, takie jak "Zapisz jako", "Przesyłanie plików" itp. w procesie automatyzacji aplikacji internetowej przy użyciu sterownika WWW selenu, ale także dla każdego, kto chce wchodzić w interakcję z określonym oknem, korzystając tylko z interfejsów API Python.

To rozwiązanie wykorzystuje moduły Win32gui, z Python. opiszę najpierw metody rodzajowe zdobyć dowolnym oknie pożądanego następnie niewielką dodanie kodu, który będzie również to użyteczne podczas automatyzowania aplikacji internetowych przy użyciu selen Webdriver.

Generic Rozwiązanie ::

import win32gui 
import re 
import SendKeys 

class WindowFinder: 
"""Class to find and make focus on a particular Native OS dialog/Window """ 
    def __init__ (self): 
     self._handle = None 

    def find_window(self, class_name, window_name = None): 
    """Pass a window class name & window name directly if known to get the window """ 
     self._handle = win32gui.FindWindow(class_name, window_name) 

    def _window_enum_callback(self, hwnd, wildcard): 
    '''Call back func which checks each open window and matches the name of window using reg ex''' 
     if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) != None: 
      self._handle = hwnd 

    def find_window_wildcard(self, wildcard): 
""" This function takes a string as input and calls EnumWindows to enumerate through all open windows """ 

    self._handle = None 
     win32gui.EnumWindows(self._window_enum_callback, wildcard) 

    def set_foreground(self): 
    """Get the focus on the desired open window""" 
     win32gui.SetForegroundWindow(self._handle) 

win = WindowFinder() 
win.find_window_wildcard(".*Save As.*") 
win.set_foreground() 
path = "D:\\File.txt"   #Path of the file you want to Save 
ent = "{ENTER}"     #Enter key stroke. 
SendKeys.SendKeys(path)   #Use SendKeys to send path string to Save As dialog 
SendKeys.SendKeys(ent)   #Use SendKeys to send ENTER key stroke to Save As dialog 

Aby użyć tego kodu trzeba dostarczyć łańcuch, który jest nazwa okna, które chcesz dostać, która w tym przypadku jest „Zapisz jako”. Podobnie możesz podać dowolną nazwę i skupić się na tym oknie. Po ustawieniu fokusu żądanego okna można użyć modułu SendKeys do wysłania pociągnięć klawiszy do okna, które w tym przypadku obejmuje wysyłanie ścieżki do pliku, w którym ma zostać zapisany plik, oraz ENTER.

Specific do Selenium Webdriver ::

Powyższy określony segment kodu mogą być używane do obsługi natywnych okien dialogowych systemu operacyjnego, które są wywoływane przez aplikację internetową podczas automatyzacji przy użyciu Selenium Webdriver z dodatkiem odrobiny kodu .

Problem, przed którym stanęł twarzą w twarz podczas korzystania z tego kodu, polega na tym, że po tym, jak kod automatyzacji kliknie na dowolne Web Element, które uruchamia okno dialogowe rodzimego OS, kontrolka utknie w tym momencie, czekając na dowolną akcję w rodzimym oknie dialogowym OS okno. Więc w zasadzie utknąłeś w tym momencie.

Prace wokół jest, aby wygenerować nowy thread użyciu Pythonthreading moduł i używać go do kliknięcia na Web Element aby wywołać okno dialogowe OS rodzimych i Twój wątek nadrzędny zostanie przeniesiony na normalnie znaleźć okno przy użyciu kodu pokazałem powyżej.

#Assume that at this point you are on the page where you need to click on a Web Element to trigger native OS window/dialog box 

def _action_on_trigger_element(_element): 
    _element.click() 

trigger_element = driver.find_element_by_id('ID of the Web Element which triggers the window') 
th = threading.Thread(target = _action_on_trigger_element, args = [trigger_element]) #Thread is created here to call private func to click on Save button 
th.start()       #Thread starts execution here 
time.sleep(1)      #Simple Thread Synchronization handle this case.   

#Call WindowFinder Class 
win = WindowFinder() 
win.find_window_wildcard(".*Save As.*") 
win.set_foreground() 
path = "D:\\File.txt"   #Path of the file you want to Save 
ent = "{ENTER}"     #Enter key stroke. 
SendKeys.SendKeys(path)   #Use SendKeys to send path string to Save As dialog 
SendKeys.SendKeys(ent)   #Use SendKeys to send ENTER key stroke to Save As dialog 

#At this point the native OS window is interacted with and closed after passing a key stroke ENTER. 
# Go forward with what ever your Automation code is doing after this point 

UWAGA ::

Podczas korzystania powyższy kod w automatyzację aplikacji internetowych, należy sprawdzić nazwę okna, którą chcesz znaleźć i przekazać, że do find_window_wildcard(). Nazwa okna zależy od przeglądarki. Na przykład. Okno uruchamiane po kliknięciu elementu do przesłania pliku nazywa się "Przesyłanie pliku" w Firefox i Otwórz w Chrome. Wymaga użycia Python2.7

Mam nadzieję, że pomoże to każdemu, kto szuka podobnego rozwiązania, niezależnie od tego, czy używać go w dowolnej formie ogólnej, czy w automatyzacji aplikacji internetowej.

EDIT:

Jeśli próbujesz uruchomić swój kod za pomocą argumentów wiersza poleceń, a następnie spróbuj użyć nici, aby znaleźć okno używając Win32gui i używać oryginalnego wątku programu kliknąć na elemencie (co jest kliknięto tutaj za pomocą wątku). Powodem jest bibliotekę urllib wygeneruje błąd podczas tworzenia nowego połączenia za pomocą gwintu.)

Referencje ::

SO Question

SenKeys

Win32gui

2

Istnieje moduł Pythona o nazwie win32ui. Znajduje się w pakiecie Python for Windows extensions. Chcesz funkcję CreateFileDialog.

Documentation

Edit: Jest to zaoszczędzić przykład dialogowe. Sprawdź dokumentację innych ustawień.

import win32ui 

if __name__ == "__main__": 
    select_dlg = win32ui.CreateFileDialog(0, ".txt", "default_name", 0, "TXT Files (*.txt)|*.txt|All Files (*.*)|*.*|") 
    select_dlg.DoModal() 

    selected_file = select_dlg.GetPathName() 
    print selected_file 
+0

Nie muszę tworzyć okna dialogowego Nowe zapamiętaj jako, ale wchodzić w interakcje z już istniejącym. Czy możesz zaproponować jakieś podejście do tego? – abhi