Как лучше всего взаимодействовать с уже открытыми собственными диалоговыми окнами ОС, такими как (Сохранить как), используя Python?

Есть ли какой-либо эффективный способ использования любого модуля Python, такого как PyWind32, для взаимодействия с уже существующими диалоговыми окнами Native OS, такими как окна «Сохранить как»?

Я пробовал искать в Google, но не помогло.

ИЗМЕНИТЬ:

1: диалоговое окно «Сохранить как» запускается, когда пользователь щелкает диалоговое окно «Сохранить как» в веб-приложении.

2: Приветствуются любые предложения по обработке любых собственных диалоговых окон ОС, которые уже запущены с помощью Python (не обязательно конкретно для веб-драйвера Selenium, я ищу общее предложение).

(Когда я публиковал вопрос, я думал, что «взаимодействие с диалоговым окном» будет неявно означать, что оно существует, как если бы я мог его создать, тогда, конечно, я мог бы взаимодействовать с ним, поскольку он находится под контролем моих программ. Прочитав первые 2 ответа, я понял, что не совсем ясен. Вот почему РЕДАКТИРОВАТЬ)

Спасибо


person abhi    schedule 21.06.2013    source источник
comment
Какое взаимодействие вы пытаетесь сделать?   -  person David Heffernan    schedule 21.06.2013
comment
@DavidHeffernan У меня есть веб-приложение, которое запускает новое диалоговое окно «Сохранить как». Мне нужно взаимодействовать в том смысле, что мне нужно щелкнуть различные параметры, представленные в диалоговом окне, и ввести путь назначения и имя файла для сохранения.   -  person abhi    schedule 22.06.2013
comment
Это для автоматизации тестирования веб-приложения? Будет ли скрипт работать в фоновом режиме в ожидании всплывающего окна? Или это часть веб-приложения?   -  person Noelkd    schedule 22.06.2013
comment
@Noelkd Да, это автоматизация веб-приложения. Скрипт работает независимо   -  person abhi    schedule 22.06.2013
comment
Разве это не тот же вопрос, что и этот?   -  person Aya    schedule 27.06.2013
comment
@Aya Вроде как, но в решениях говорится об использовании AutoIt или редактировании профиля вашего браузера, чтобы упростить сохранение файла. Я ищу более общий ответ, с помощью которого я могу обрабатывать любые собственные диалоговые окна ОС, такие как просмотр файлов, загрузка и т. д.   -  person abhi    schedule 27.06.2013
comment
Ну, это почти наверняка возможно, но это было бы полной головной болью и очень специфично для ОС и конкретного случая. Если «Сохранить как» — ваш единственный вариант использования, я бы предложил использовать более простую альтернативу.   -  person Aya    schedule 27.06.2013
comment
Решение @Aya AutoIT мне показалось не очень хорошим, должно быть какое-то решение, в котором я могу использовать windowsAPi для этого.) Я сталкивался с некоторыми, экспериментируя с ними, опубликую решение, если все работает хорошо.   -  person abhi    schedule 27.06.2013
comment
@abhi Я больше думал о решении, которое не использует «Сохранить как» и просто загружается автоматически. Если целью является тестирование вашего веб-приложения, кажется ненужным тестировать сам веб-браузер.   -  person Aya    schedule 27.06.2013
comment
@Aya В моем приложении я сталкиваюсь со многими родными диалоговыми окнами ОС, такими как «Загрузить файл», «Просмотреть файл» и т. Д. Вот почему я ищу универсальное решение. Возможно, в будущем, если мне понадобится сделать что-то подобное, в истории нет веб-браузера, я смогу это сделать. Я нашел решение, и оно работает нормально. Я опубликую решение в ближайшее время.   -  person abhi    schedule 27.06.2013
comment
@abhi Достаточно честно. Было бы интересно увидеть ваше решение. Та, которую я имел в виду, была безумно сложной. :)   -  person Aya    schedule 27.06.2013
comment
@Aya Пожалуйста, посмотрите решение, которое я опубликовал. Любая обратная связь будет здорово. Также я хотел бы прочитать решение, которое вы придумали.   -  person abhi    schedule 27.06.2013
comment
@abhi +1 за ваш ответ. Я бы сделал что-то подобное, за исключением того, что использовал модуль ctypes для прямого доступа к Win32 API. Я также ограничил бы поиск правильного дескриптора окна только теми, которые принадлежат процессу браузера, на случай, если у вас открыто какое-либо другое приложение с активным диалоговым окном «Сохранить как». Тем не менее, я бы, вероятно, никогда не использовал что-то подобное на практике. Если бы я хотел протестировать такие вещи, как загрузка/выгрузка, я бы сделал это с чем-то вроде mechanize, предполагая, что он поддерживает такие вещи, в противном случае свернул бы свой собственный с httplib или чем-то подобным.   -  person Aya    schedule 27.06.2013
comment
@Aya Спасибо, что предложили механизировать, я посмотрю на это. Еще раз спасибо за предложения. Подсказка httplib дала мне новое направление. Будет работать над этим. :)   -  person abhi    schedule 27.06.2013


Ответы (2)


В поисках возможного решения для этого я наткнулся на несколько решений для SO и других. Некоторые из них использовали AutoIT или редактировали профиль браузера, чтобы он сохранял файл напрямую без запроса.

Я нашел все это решение слишком специфичным, так как вы можете решить проблему с диалоговым окном «Сохранить как», отредактировав профиль браузера, но если позже вам нужно будет обработать какое-то другое окно, вы застряли. Поскольку использование AutoIT является излишним, это напрямую противоречит тому факту, что я выбираю Python для выполнения этой задачи. (Я имею в виду, что Python сам по себе такой мощный, в зависимости от какого-то другого инструмента строго НЕТ НЕТ для любого Pythonist)

Итак, после долгого поиска возможного общего решения этой проблемы, которое не только служит любому, кто хочет обрабатывать любые диалоговые окна собственной ОС, такие как «Сохранить как», «Загрузка файла» и т. д., в процессе автоматизации веб-приложения с использованием селена веб-драйвер, но и любому, кто хочет взаимодействовать с конкретным окном, используя только Python API.

В этом решении используются Win32gui, SendKeys модули Python. Сначала я объясню общий метод для получения доступа к любому желаемому окну, а затем небольшое добавление кода, которое также сделает его пригодным для использования при автоматизации веб-приложения с помощью Selenium Webdriver.

Общее решение::

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

Чтобы использовать этот код, вам нужно указать строку, которая является именем окна, которое вы хотите получить, в данном случае «Сохранить как». Точно так же вы можете указать любое имя и сфокусировать это окно. Как только вы сфокусируетесь на нужном окне, вы можете использовать модуль SendKeys для отправки нажатий клавиш в окно, что в данном случае включает отправку пути к файлу, в котором вы хотите сохранить файл, и ENTER.

Особенно для Selenium Webdriver::

Указанный выше сегмент кода можно использовать для обработки собственных диалоговых окон ОС, которые запускаются через веб-приложение во время автоматизации с использованием Selenium Webdriver с добавлением небольшого фрагмента кода.

Проблема, с которой вы столкнетесь, с которой я столкнулся при использовании этого кода, заключается в том, что как только ваш код автоматизации щелкает любой Web Element, который запускает диалоговое окно собственной ОС, элемент управления зависает в этой точке, ожидая каких-либо действий в диалоговом окне собственной ОС. Так что в основном вы застряли в этой точке.

Обходной путь заключается в том, чтобы сгенерировать новый thread с помощью модуля Python threading и использовать его, чтобы щелкнуть Web Element, чтобы вызвать диалоговое окно собственной ОС, и ваш родительский поток будет двигаться в обычном режиме, чтобы найти окно, используя код, который я показал выше.

#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

ПРИМЕЧАНИЕ::

При использовании приведенного выше кода для автоматизации веб-приложения проверьте имя окна, которое вы хотите найти, и передайте его find_window_wildcard(). Название окон зависит от браузера. Например. Окно, которое запускается, когда вы нажимаете на элемент для загрузки файла, называется «Загрузка файла» в Firefox и «Открыть» в Chrome. Использует Python2.7

Я надеюсь, что это поможет любому, кто ищет подобное решение, использовать ли его в какой-либо универсальной форме или для автоматизации веб-приложения.

ИЗМЕНИТЬ:

Если вы пытаетесь запустить свой код с помощью аргументов командной строки, попробуйте использовать поток, чтобы найти окно, используя Win32gui, и используйте исходный программный поток, чтобы щелкнуть элемент (который щелкается здесь с помощью потока). Причина в том, что библиотека urllib выдаст ошибку при создании нового соединения с использованием потока.)

Использованная литература::

SO Вопрос

SenKeys

Win32gui

person abhi    schedule 27.06.2013

Существует модуль Python под названием win32ui. Его можно найти в пакете Python for Windows extensions. Вам нужна функция CreateFileDialog.

Документация

Редактировать: это пример диалога сохранения. Прочие настройки смотрите в документации.

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
person dilbert    schedule 21.06.2013
comment
Мне не нужно создавать новое диалоговое окно «Сохранить как», а нужно взаимодействовать с уже существующим. Можете ли вы предложить какой-то подход для этого? - person abhi; 22.06.2013