当前位置: 首页 > 面试题库 >

Windows上适用于Python 3.1的SendKeys

蓬英逸
2023-03-14
问题内容

最新的Python Sendkeys模块适用于Python 2.6。我自己不能升级它,因为它需要重新编译C模块。

有谁知道将密钥发送到窗口的相当简单的替代方法?

使用win32ui.FindWindow(),我可以找到正确的窗口,然后使用PyCWnd.SetActiveWindow()将其激活,因此所需要的只是将击键发送到活动窗口的简单方法。

目的是执行菜单项。

该应用程序是用Delphi编写的,没有我所知道的任何进程间接口。


问题答案:

这是一个调用user32.SendInput()的工作模块。

不完美,但可用。

编辑:

昨天,我使用一个类制作了一个版本,并在正在运行的tkinter应用程序中使用它。当我有时间清理它时,会把它放在这里。

在下面的文档字符串中添加了此代码:

[如果我在个人资料中的文件夹中工作,可以。
这些问题是在另一个分区上工作时发生的。
文件权限还可以,所以不知道阻止了SendInput的内容。]

SciTE仍需要 完整的确切 窗口标题。

#!/usr/bin/python
# -*- coding: utf-8 -*-

''' send_input for python 3, from jh45dev@gmail.com

code from Daniel F is adapted here. The original is at:
http://mail.python.org/pipermail/python-win32/2005-April/003131.html


SendInput sends to the window that has the keyboard focus.
That window must not be minimized.


There seem to be some strange limitations with user32.SendInput()
Here is what happened in my testing (on Vista sp2).

 [edit: It is OK if I work from a folder within my profile.    
 These problems happened when working on another partition.    
 File permissions were OK, so do not know what blocked SendInput.]

1
I opened Notepad from the Start menu,
then in Notepad opened test.txt,
and all worked fine.

2
I opened Notepad by opening test.txt in Explorer.
find_window() found Notepad, but user32.SendInput() had no effect.
If Notepad was minimized, it did not get restored or focussed.

The same happened with SciTE and Notepad2.


Another strangeness:
For SciTE I had to put in the whole window title, eg "test.txt - SciTE",
but for Notepad and Notepad2, only the app name, eg "Notepad".


'''

import ctypes as ct
from win32con import SW_MINIMIZE, SW_RESTORE
from win32ui import FindWindow, error as ui_err
from time import sleep


class cls_KeyBdInput(ct.Structure):
    _fields_ = [
        ("wVk", ct.c_ushort),
        ("wScan", ct.c_ushort),
        ("dwFlags", ct.c_ulong),
        ("time", ct.c_ulong),
        ("dwExtraInfo", ct.POINTER(ct.c_ulong) )
    ]

class cls_HardwareInput(ct.Structure):
    _fields_ = [
        ("uMsg", ct.c_ulong),
        ("wParamL", ct.c_short),
        ("wParamH", ct.c_ushort)
    ]

class cls_MouseInput(ct.Structure):
    _fields_ = [
        ("dx", ct.c_long),
        ("dy", ct.c_long),
        ("mouseData", ct.c_ulong),
        ("dwFlags", ct.c_ulong),
        ("time", ct.c_ulong),
        ("dwExtraInfo", ct.POINTER(ct.c_ulong) )
    ]

class cls_Input_I(ct.Union):
    _fields_ = [
        ("ki", cls_KeyBdInput),
        ("mi", cls_MouseInput),
        ("hi", cls_HardwareInput)
    ]

class cls_Input(ct.Structure):
    _fields_ = [
        ("type", ct.c_ulong),
        ("ii", cls_Input_I)
    ]


def find_window( s_app_name ):

    try:
        window1 = FindWindow(  None, s_app_name,)
        return window1
    except ui_err:
        pass
    except:
        raise

    try:
        window1 = FindWindow( s_app_name, None, )
        return window1
    except ui_err:
        return None
    except:
        raise


def make_input_objects( l_keys ):

    p_ExtraInfo_0 = ct.pointer(ct.c_ulong(0))

    l_inputs = [ ]
    for n_key, n_updown in l_keys:
        ki = cls_KeyBdInput( n_key, 0, n_updown, 0, p_ExtraInfo_0 )
        ii = cls_Input_I()
        ii.ki = ki
        l_inputs.append( ii )

    n_inputs = len(l_inputs)

    l_inputs_2=[]
    for ndx in range( 0, n_inputs ):
        s2 = "(1, l_inputs[%s])" % ndx
        l_inputs_2.append(s2)
    s_inputs = ', '.join(l_inputs_2)


    cls_input_array = cls_Input * n_inputs
    o_input_array = eval( "cls_input_array( %s )" % s_inputs )

    p_input_array = ct.pointer( o_input_array )
    n_size_0 = ct.sizeof( o_input_array[0] )

    # these are the args for user32.SendInput()
    return ( n_inputs, p_input_array, n_size_0 )

    '''It is interesting that o_input_array has gone out of scope
    by the time p_input_array is used, but it works.'''


def send_input( window1, t_inputs, b_minimize=True ):

    tpl1 = window1.GetWindowPlacement()
    was_min = False
    if tpl1[1] == 2:
        was_min = True
        window1.ShowWindow(SW_RESTORE)
        sleep(0.2)

    window1.SetForegroundWindow()
    sleep(0.2)
    window1.SetFocus()
    sleep(0.2)
    rv = ct.windll.user32.SendInput( *t_inputs )

    if was_min and b_minimize:
        sleep(0.3) # if the last input was Save, it may need time to take effect
        window1.ShowWindow(SW_MINIMIZE)

    return rv



# define some commonly-used key sequences
t_ctrl_s = (  # save in many apps
    ( 0x11, 0 ),
    ( 0x53, 0 ),
    ( 0x11, 2 ),
)
t_ctrl_r = (  # reload in some apps
    ( 0x11, 0 ),
    ( 0x52, 0 ),
    ( 0x11, 2 ),
)


def test():

    # file > open; a non-invasive way to test
    t_ctrl_o = ( ( 0x11, 0 ), ( 0x4F, 0 ), ( 0x11, 2 ), )

    # writes "Hello\n"
    # 0x10 is shift.  note that to repeat a key, as with 4C here, you have to release it after the first press
    t_hello = ( ( 0x10, 0 ), ( 0x48, 0 ), ( 0x10, 2 ), ( 0x45, 0 ), ( 0x4C, 0 ), ( 0x4C, 2 ), ( 0x4C, 0 ), ( 0x4F, 0 ), ( 0x0D, 0 ), )


    l_keys = [ ]
    ## l_keys.extend( t_ctrl_o )
    l_keys.extend( t_hello )
    l_keys.extend( t_ctrl_s )

    ## s_app_name = "SciTE"
    ## s_app_name = "(Untitled) - SciTE"
    s_app_name = "test.txt - SciTE"
    ## s_app_name = "Notepad2"
    ## s_app_name = "Notepad"

    window1 = find_window( s_app_name )
    if window1 == None:
        print( "%r has no window." % s_app_name )
        input( 'press enter to close' )
        exit()

    t_inputs = make_input_objects( l_keys )

    n = send_input( window1, t_inputs )

    ## print( "SendInput returned: %r" % n )
    ## print( "GetLastError: %r" % ct.windll.kernel32.GetLastError() )
    ## input( 'press enter to close' )



if __name__ == '__main__':
    test()


 类似资料:
  • 问题内容: 我在阅读有关docker的一个不错的问题-回答了有关docker实现细节的概述。我想知道在Windows平台上是否可以做这样的事情。 是否存在Windows替代Docker? 从理论上讲,可以使用其他(基于Windows的)组件来构建它吗? 更新1 : 稍微相关的问题(沙盒处理):是否存在用于Windows平台的轻型,可编程的Sandbox API? Update2 :: 有关如何在W

  • 所以我使用这种方法写入文件,它在windows上运行完全正常,但在mac上运行时,它会创建文件,但它们是空的。 我知道数据是正确的,因为它打印正确。感谢您的任何帮助,这真的让我绊倒了。

  • 正在运行PHP IIS服务器。 使用未定义常量OCI_CRED_EXT时出错-假定为“OCI_CRED_EXT”(这将在PHP的未来版本中引发错误) 通过运行php artiasan,与Oracle数据库的连接正在工作。 配置: Windows 10 x64专业版20H2 手动安装7.3非线程安全x86添加路径到环境 IIS服务器版本10 拉维尔8 保监处8.2。2对于WIndows非线程安全(N

  • 因此,我正在构建这个游戏和一个地图编辑器/sdk类型的协议。在我运行w7的台式电脑和我的朋友运行w10的笔记本电脑上,一切都工作得非常好。我可以添加对象并四处移动它们(每个对象都有一个自动更新属性窗口),一切都很好。 我目前正在旅行,所以我决定将项目复制到我的macbook上。UI上的一切都仍然有效,除了停止渲染的东西。我知道对象存在于应用程序中,因为我可以单击它们所在的位置,属性更新就像在我的桌

  • 问题内容: 我在JAI和ImageIO库中搜索了64位窗口,但没有找到这些窗口的任何版本。6-7年前在Java Bug跟踪系统上的最后64位胜诉请求。 我认为,jai的开发人员不会为Win64发布任何版本。:( 我的问题是,我们可以为64位Windows从它们的源构建jai和imageio吗?怎么样? 非常感谢… 问题答案: 从源语言的角度来看,JAI和JAI Image I / O由两部分组成:

  • 问题内容: 我已经在Internet上搜索了一段时间,但无法找到有关如何在Windows下安装适用于Python 3.x的OpenCV的详细说明。 如果他/她已经成功地为预编译的二进制文件或源代码为OpenCV 2.x或OpenCV 3版本安装了适用于Python 3.x的OpenCV,我将不胜感激。。X。 问题答案: OpenCV 3添加了对python 3+的支持。它仍然处于Alpha状态,目