本文介绍: 我的报错是t1线程先运行,t2线程排在后面,当t2线程向t1线程发送消息时报错的,也就是说线程t1的优先级较高。因为我代码里面开启了两个线程,用2个线程去跑,即2个进程。这两个线程的优先级是不一样的。优先级低的是不能向优先级高的发送消息,即使他们是在同一个用户的权限下运行。原因:网上查了下是由于windows安全机制导致 integrity level低的进程不能向高的进程发消息。第三种方案:在源代码本身修改注册表,来提高代码本身的权限,然后去运行。但是我的代码是爬虫代码,我不想设置管理员运行。

部分python脚本:

def sap_logon():
    try:
        os.system('taskkill /F /IM saplogon.exe')
        print("SAP程序已关闭!")
    except:
        print("SAP程序没打开!")
    sap_app = r"C:\Program Files (x86)\SAPFrontEnd\SAPgui\saplogon.exe"
    subprocess.Popen(sap_app)
    time.sleep(4)

    # 连接SAP
    app = Application(backend='uia').connect(title_re="SAP Logon 730")

    # 选择SAP窗口
    dlg = app.window(title_re="SAP Logon 730")
    # 点击登录按钮
    dlg["登录(O)Button"].click()
    # 找到SAP登录窗口,并使他最大化
    top1= win32gui.FindWindow("SAP_FRONTEND_SESSION","SAP")
    win32gui.ShowWindow(top1,win32con.SW_MAXIMIZE)
    time.sleep(2)

    # 获取客户端对象
    SapGuiAuto = win32com.client.GetObject("SAPGUI")

    application = SapGuiAuto.GetScriptingEngine
    connection = application.Children(0)
    session = connection.Children(0)

def enum_child_windows_proc():
    time.sleep(15)
    hwndParent = win32gui.FindWindow("#32770","SAP Logon")
    hwndChild =  win32gui.FindWindowEx(hwndParent,None,"Button",None)
    print(hwndChild)
    # 发送模拟的鼠标点击消息,
    win32gui.PostMessage(hwndChild, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, 0)  # 选择确定按钮
    win32gui.PostMessage(hwndChild, win32con.WM_LBUTTONUP, 0, 0)  # 点击确定按钮

if __name__ == '__main__':
    time.sleep(0.5)
#     # 创建线程组1去执行登录
    t1 = Thread(target=sap_logon)

    # 创建线程组2去执行确认登录
    t2 = Thread(target=enum_child_windows_proc)

    # 开始执行线程
    t1.start()
    t2.start()
    # 主线程等待子线程执行
    t1.join()
    t2.join()
    time.sleep(1)

报错信息:报错信息“pywintypes.error: (5, ‘PostMessage’, ‘拒绝访问。’)”

原因:网上查了下是由于windows安全机制导致 integrity level低的进程不能向高的进程发消息。
确实是涉及到权限问题。
因为我代码里面开启了两个线程,用2个线程去跑,即2个进程。这两个线程的优先级是不一样的。优先级低的是不能向优先级高的发送消息,即使他们是在同一个用户的权限下运行。

所以,解决方案一:
使用管理员运行,即使用管理员打开pycharm,然后运行程序。问题解决。
但是我的代码是爬虫代码,我不想设置管理员运行。需要找第二种方法

方案二:设置线程优先级
我的报错是t1线程先运行,t2线程排在后面,当t2线程向t1线程发送消息时报错的,也就是说线程t1的优先级较高。解决的方案是设置t1为低级别优先级。t1.daemon = True

if __name__ == '__main__':
    time.sleep(0.5)
#     # 创建线程组1去执行登录
    t1 = Thread(target=sap_logon)

    # 创建线程组2去执行确认登录
    t2 = Thread(target=enum_child_windows_proc)

    # 设置t1线程为后台线程,优先级别较低
    t1.daemon = True

    # 开始执行线程
    t1.start()
    t2.start()
    # 主线程等待子线程执行
    t1.join()
    t2.join()
    time.sleep(1)

或者通过setPriority(threading.Thread.MAX_PRIORITY)来设置优先级别。

第三种方案:在源代码本身修改注册表,来提高代码本身的权限,然后去运行。(这个方是把双刃剑)

def run_mian():
    key = 'QuickPop'  # 注册表名称
    value = 'data'  # 注册表数据

    # 打开注册表目录,KEY_ALL_ACCESS获取所有的权限
    handle = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'SOFTWAREMicrosoftWindowsCurrentVersionRun', 0,
                                 win32con.KEY_ALL_ACCESS)
    # 获取注册表的值
    values = getRegValue(handle, key)
    print('getValue:', values)

    if values != value:
        # 设置参数 不存在则新增
        setValue = setRegValue(handle, key, value)
        print('setValue:', setValue)

# 获取注册表值 不存在返回False
def getRegValue(handle, key):
    try:
        return win32api.RegQueryValueEx(handle, key)[0]
    except Exception as e:
        return False

# 设置注册表值
def setRegValue(handle, key, value):
    try:
        return win32api.RegSetValueEx(handle, key, 0, win32con.REG_SZ, value)
    except Exception as e:
        return False

if __name__ == '__main__':
    time.sleep(0.5)
	run_main()

原文地址:https://blog.csdn.net/m0_48830183/article/details/135996794

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_65447.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注