shell.sendkeys () Заставляет программу перестать отвечать и отправляет неверные ключи - PullRequest
0 голосов
/ 14 марта 2020

Это мой первый пост, так что, надеюсь, я следую правильному этикету и формату.

Я использую shell.sendkeys () для заполнения пробелов, которые нелегко автоматизировать при переключении между различными приложениями , Приведенный ниже код является упрощением выдержки из сценария из 7000 строк. Большой скрипт также широко использует win32 gui .Enum Windows () для перемещения, изменения размера, минимизации, максимизации и переключения между различными windows. Я предполагаю, что проблема напрямую связана с shell.sendkeys (), но это может быть связано с другими факторами.

Чтобы определить и описать конкретные c ситуации, в которых возникают проблемы, потребуется немного работы. подходите, но это кажется довольно случайным.

Основная проблема заключается в том, что приложение, которое получает ключи, часто перестает отвечать на запросы. Окно отображается нормально, но любое нажатие клавиши или мыши в этом окне не даст никакого эффекта. Ключи чаще всего отправляются на Microstation и Chrome. Проблема может быть решена закрытием (диспетчером задач) программы, получающей ключи и перезапускающей ее, или закрытием окна python cmd. Это происходит достаточно часто, чтобы соотношение затрат и выгод от использования подпрограммы лишь незначительно отклонялось к положительному.

Другая проблема заключается в отправке строк через подпрограмму, как в "s * some string". Наиболее распространенные строки, которые я отправляю - это пути к папкам или файлам. shell.sendkeys () часто отправляет ";" вместо ":" и "|" вместо "\". (Отправлено еще несколько менее распространенных неправильных ключей).

import win32com
import win32com.client
from pynput import keyboard
import time
import win32gui
import win32api
import win32con
from win32gui import GetWindowText, GetForegroundWindow

def ghostUser(keyArray, appToActivate):

        #Format inputs as follows:
        #Send single key: Add key name as specified at https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/8c6yea83(v=vs.84)
        #Send the same key multiple times: (key)#(number of times to send)
        #Wait: w*(number of seconds to wait)
        #Continue following user input: wait#(message to display for user)
        #Left click mouse: leftClick,(x position),(y position)
        #Right click mouse: rightClick,(x position), (y position)
        #Drag mouse: drag,(starting x position),(starting y position),(ending x position),(ending y position)
        #Type string: s*(string to type)
        #Press esc at any time to abort

    shell = win32com.client.Dispatch("WScript.Shell")

    if appToActivate != "":
        shell.AppActivate(appToActivate)

    def on_press_continue(key):

        try:
            k = key.char
        except:
            k = key.name
        if k == "scroll_lock": 
            return False

    def on_press_escape(key):
        try: k = key.char # single-char keys
        except: k = key.name # other keys
        if key == keyboard.Key.esc: return False # stop listener

    print "ghostUser() Sending keys to '" + appToActivate + "': "
    print str(keyArray)

    with keyboard.Listener(on_press_escape) as listener:

        i = 0
        for k in keyArray:
            if not listener.running:
                print "ESC was pressed."
                break
            i += 1
            if "*" in k:
                kSplit = k.split("*")
                if kSplit[0] == "s":
                    for char in kSplit[1].replace("' + '", ""):
                        if not listener.running:
                            print "ESC was pressed."
                            break
                        shell.SendKeys(char)
                        time.sleep(0.10)
                if kSplit[0] == "w":
                    time.sleep(float(kSplit[1]))
            if "#" in k and not "wait" in k:
                kSplit = k.split("#")
                for l in range (0, int(kSplit[1])):
                    if not listener.running:
                        print "ESC was pressed."
                        break
                    shell.SendKeys(kSplit[0])
                    time.sleep(0.5)
            if "leftClick" in k:
                win32api.SetCursorPos((int(k.split(",")[1]),int(k.split(",")[2])))
                flags, hcursor, (x,y) = win32gui.GetCursorInfo()
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
            if "doubleClick" in k:
                win32api.SetCursorPos((int(k.split(",")[1]),int(k.split(",")[2])))
                flags, hcursor, (x,y) = win32gui.GetCursorInfo()
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
            if "rightClick" in k:
                win32api.SetCursorPos((int(k.split(",")[1]),int(k.split(",")[2])))
                flags, hcursor, (x,y) = win32gui.GetCursorInfo()
                win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,x,y,0,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,x,y,0,0)
            if "drag" in k:
                win32api.SetCursorPos((int(k.split(",")[1]),int(k.split(",")[2])))
                flags, hcursor, (x,y) = win32gui.GetCursorInfo()
                win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,x,y,0,0)
                win32api.SetCursorPos((int(k.split(",")[3]),int(k.split(",")[4])))
                flags, hcursor, (x,y) = win32gui.GetCursorInfo()                
                win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,x,y,0,0)
            if "wait" in k:

                currentActiveWindow = GetWindowText(GetForegroundWindow())

                message = k.split("#")[0]
                print message + " Press scroll lock when ready to proceed: "
                infinity = True

                with keyboard.Listener(on_press_continue) as listener2:
                    while infinity == True:
                        if listener2.running == False:
                            shell.AppActivate(appToActivate)
                            break
                shell.AppActivate(currentActiveWindow)

            specialStrings = ["*", "#", "leftClick", "rightClick", "doubleClick", "drag", "wait"]
            if not any (ss in k for ss in specialStrings):
                shell.SendKeys(k)

            time.sleep(0.5)
            print "Sequences entered: " + str(i) + "\t" + "'" + k + "'"

keysToSend = ["{TAB}#20", "^k", "s*www.google.com", "~","wait#Press scroll lock when page loads.", "leftClick,2103,737", "rightClick,2103,737", "drag,2103,737,2200,800"]
ghostUser(keysToSend, "Chrome")

...