部分python脚本:
def sap_logon():try:os.system('taskkill /F /IM saplogon.exe')print("SAP程序已关闭!")except:print("SAP程序没打开!")sap_app = r"C:\\Program Files (x86)\\SAP\FrontEnd\\SAPgui\\saplogon.exe"subprocess.Popen(sap_app)time.sleep(4)# 连接SAPapp = 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.GetScriptingEngineconnection = 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, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 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 Falseif __name__ == '__main__':time.sleep(0.5)run_main()