|
@@ -9,9 +9,52 @@ import win32gui, win32con, win32process
|
|
|
import psutil
|
|
|
import urllib.parse
|
|
|
import subprocess
|
|
|
+import autoit
|
|
|
+import datetime
|
|
|
|
|
|
hug.API(__name__).http.output_format = hug.output_format.json
|
|
|
+# exePath = r"C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE"
|
|
|
+exePath = r"C:\Program Files\Microsoft Office\Office16\EXCEL.EXE"
|
|
|
|
|
|
+# 红桃3选项卡位置
|
|
|
+hongTao3PointX = 497
|
|
|
+hongTao3PointY = 47
|
|
|
+
|
|
|
+
|
|
|
+# 数据刷新按钮
|
|
|
+refreshButtonPointX = 247
|
|
|
+refreshButtonPointY = 102
|
|
|
+
|
|
|
+# 刷新工作簿按钮
|
|
|
+refreshSheetPointX = 274
|
|
|
+refreshSheetPointY = 174
|
|
|
+
|
|
|
+# 弹框的登录按钮位置
|
|
|
+loginButtonPointX = 518
|
|
|
+loginButtonPointY = 437
|
|
|
+
|
|
|
+# 刷新完成按钮
|
|
|
+refreshEndPointX = 747
|
|
|
+refreshEndPointY = 451
|
|
|
+
|
|
|
+# 用来随机的最大最小x、y坐标
|
|
|
+minPointX = 511
|
|
|
+maxPointX = 1000
|
|
|
+minPointY = 282
|
|
|
+maxPointY = 600
|
|
|
+
|
|
|
+# excel在进程中的名称
|
|
|
+excelProcessName = "EXCEL.EXE"
|
|
|
+
|
|
|
+# 登录提示框
|
|
|
+# hongTao3LoginButtonName = "WindowsForms10.Window.8.app.0.182b0e9_r56_ad2"
|
|
|
+hongTao3LoginButtonName = "WindowsForms10.Window.8.app.0.182b0e9_r55_ad2"
|
|
|
+
|
|
|
+# 刷新中的按钮名称
|
|
|
+refreshIngButtonName = "WindowsForms10.Window.8.app.0.182b0e9_r57_ad2"
|
|
|
+
|
|
|
+# 刷新完成的按钮名称
|
|
|
+refreshEndButtonName = "#32770"
|
|
|
|
|
|
def getProcessName(hwnd):
|
|
|
tid, pid = win32process.GetWindowThreadProcessId(hwnd)
|
|
@@ -31,41 +74,41 @@ def getText(hwnd):
|
|
|
|
|
|
|
|
|
# 检验卓创的登录失效按钮
|
|
|
-def checkLoginInvalid():
|
|
|
- # 登录失效的弹框(类名: Button)
|
|
|
- pointX = 1047
|
|
|
- pointY = 604
|
|
|
- hwnd = win32gui.WindowFromPoint((pointX, pointY))
|
|
|
- # print("检验卓创的登录失效按钮:", hwnd)
|
|
|
- if hwnd != 0:
|
|
|
- print("检验卓创的登录失效按钮:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
|
|
|
- if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "Button":
|
|
|
- print("好吧,登录失效了")
|
|
|
- pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
- pyautogui.click()
|
|
|
- time.sleep(1)
|
|
|
- return True
|
|
|
- else:
|
|
|
- return False
|
|
|
- else:
|
|
|
- return False
|
|
|
+# def checkLoginInvalid():
|
|
|
+# # 登录失效的弹框(类名: Button)
|
|
|
+# # pointX = 1047
|
|
|
+# # pointY = 604
|
|
|
+# # hwnd = win32gui.WindowFromPoint((pointX, pointY))
|
|
|
+# hwnd = win32gui.GetForegroundWindow()
|
|
|
+# # print("检验卓创的登录失效按钮:", hwnd)
|
|
|
+# if hwnd != 0:
|
|
|
+# print("检验卓创的登录失效按钮:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
|
|
|
+# if getProcessName(hwnd) == excelProcessName and getClassName(hwnd) == hongTao3LoginButtonName:
|
|
|
+# print("好吧,登录失效了")
|
|
|
+# pyautogui.moveTo(loginButtonPointX, loginButtonPointY, 0.5)
|
|
|
+# pyautogui.click()
|
|
|
+# time.sleep(1)
|
|
|
+# return True
|
|
|
+# else:
|
|
|
+# return False
|
|
|
+# else:
|
|
|
+# return False
|
|
|
|
|
|
|
|
|
# 检验卓创的登录按钮
|
|
|
def checkHongtaoLoginButton():
|
|
|
# 卓创登录的弹框(类名: WindowsForms10.BUTTON.app.0.182b0e9_r93_ad2)
|
|
|
- pointX = 1042
|
|
|
- pointY = 564
|
|
|
- hwnd = win32gui.WindowFromPoint((pointX, pointY))
|
|
|
+ # hwnd = win32gui.WindowFromPoint((loginButtonPointX, loginButtonPointY))
|
|
|
+ hwnd = win32gui.GetForegroundWindow()
|
|
|
# print("检验卓创的登录按钮:", hwnd)
|
|
|
if hwnd != 0:
|
|
|
className = getClassName(hwnd)
|
|
|
print("检验卓创的登录按钮:processName:", getProcessName(hwnd), ",类名:", className)
|
|
|
lenClassName = len(className)
|
|
|
# if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "WindowsForms10.BUTTON.app.0.182b0e9_r93_ad2":
|
|
|
- if getProcessName(hwnd) == "EXCEL.EXE" and className != "Button":
|
|
|
+ if getProcessName(hwnd) == excelProcessName and className == hongTao3LoginButtonName:
|
|
|
print("开始卓创登录")
|
|
|
- pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
+ pyautogui.moveTo(loginButtonPointX, loginButtonPointY, 0.5)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
return True
|
|
@@ -79,32 +122,51 @@ def checkHongtaoLoginButton():
|
|
|
def checkRefreshEnd():
|
|
|
# 登录失效的弹框(类名: Button)
|
|
|
# 完成了,点击结束
|
|
|
- pointX = 1072
|
|
|
- pointY = 605
|
|
|
|
|
|
+ # 等2秒吧
|
|
|
+ time.sleep(2)
|
|
|
i = 1
|
|
|
n = 1
|
|
|
+
|
|
|
+ # hwnd为0的次数,如果超过5次,那么就终止
|
|
|
+ hwndN = 0
|
|
|
while i < 2:
|
|
|
- hwnd = win32gui.WindowFromPoint((pointX, pointY))
|
|
|
+ # hwnd = win32gui.WindowFromPoint((refreshEndPointX, refreshEndPointY))
|
|
|
+ hwnd = win32gui.GetForegroundWindow()
|
|
|
# print("检验卓创的数据刷新组件:", hwnd)
|
|
|
print("第", n, "次检测")
|
|
|
n = n + 1
|
|
|
+ print("hwnd:", hwnd)
|
|
|
if hwnd != 0:
|
|
|
+ # hwnd为0的次数置空
|
|
|
+ hwndN = 0
|
|
|
print("检验卓创的数据刷新组件:processName:", getProcessName(hwnd), ",类名:", getClassName(hwnd))
|
|
|
- if getProcessName(hwnd) == "EXCEL.EXE" and getClassName(hwnd) == "Button":
|
|
|
+ if getProcessName(hwnd) == excelProcessName and getClassName(hwnd) == refreshEndButtonName:
|
|
|
print("ok,刷新完成了")
|
|
|
- pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
+ pyautogui.moveTo(refreshEndPointX, refreshEndPointY, 0.5)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
return True
|
|
|
- else:
|
|
|
- ## 不用n=2的原因,是因为那个遮罩层可能没那么快出来,万一真实很快就被刷出来了,那么超时500s后,就超时关闭吧
|
|
|
- if n >= 500 and getClassName(hwnd) == "EXCEL7":
|
|
|
- print("ok,应该是很快就刷新完成了")
|
|
|
- return True
|
|
|
- time.sleep(1)
|
|
|
+
|
|
|
+ # 不用n=2的原因,是因为那个遮罩层可能没那么快出来,万一真实很快就被刷出来了,那么超时500s后,就超时关闭吧
|
|
|
+ if n > 500:
|
|
|
+ print("超时500s,默认执行完成吧")
|
|
|
+ return True
|
|
|
+
|
|
|
+ if getProcessName(hwnd) != excelProcessName:
|
|
|
+ print("目前活动窗口与实际不符,终止执行")
|
|
|
+ return False
|
|
|
+
|
|
|
+ # 等待1s执行
|
|
|
+ time.sleep(1)
|
|
|
else:
|
|
|
- return
|
|
|
+ # hwnd为0的次数,如果超过5次,那么就终止
|
|
|
+ if hwndN > 5:
|
|
|
+ return False
|
|
|
+
|
|
|
+ hwndN = hwndN + 1
|
|
|
+ # 等待2s执行
|
|
|
+ time.sleep(2)
|
|
|
|
|
|
|
|
|
@hug.get('/hongtao/server')
|
|
@@ -115,23 +177,30 @@ def mysteel_chemical_server():
|
|
|
@hug.get('/hongtao/refresh')
|
|
|
def mysteel_chemical_refresh(FilePath):
|
|
|
pyautogui.FAILSAFE = False
|
|
|
- # FilePath = urllib.parse.unquote(FilePath)
|
|
|
- FilePath = FilePath.replace('"', '')
|
|
|
+ file_path = FilePath
|
|
|
+ print(FilePath)
|
|
|
+ screen_width, screen_height = pyautogui.size()
|
|
|
+ print("当前时间:{};当前屏幕分辨率:{} x {}".format(datetime.datetime.now(), screen_width, screen_height))
|
|
|
+
|
|
|
+ pyautogui.FAILSAFE = False
|
|
|
+
|
|
|
+ file_path = file_path.replace('"', '')
|
|
|
|
|
|
+ # 显示桌面
|
|
|
pyautogui.hotkey('win', 'd')
|
|
|
|
|
|
# return "a"
|
|
|
try:
|
|
|
- fileFullPath = FilePath
|
|
|
- print("fileFullPath start")
|
|
|
- print(fileFullPath)
|
|
|
+ file_path = urllib.parse.unquote(file_path)
|
|
|
+ fileFullPath = file_path
|
|
|
|
|
|
- fileFullPath = fileFullPath.replace(r"\\", "\\")
|
|
|
- # fileFullPath = fileFullPath.replace("\\\\", "\\")
|
|
|
+ # print("full_path start")
|
|
|
+ fileFullPath = fileFullPath.replace("\\\\", "\\")
|
|
|
|
|
|
- # print("fileFullPath:", fileFullPath)
|
|
|
+ print("文件路径:", fileFullPath)
|
|
|
|
|
|
- if os.path.exists(fileFullPath) == False:
|
|
|
+ if not os.path.exists(fileFullPath):
|
|
|
+ print("文件不存在")
|
|
|
return
|
|
|
|
|
|
# app = xw.App(visible=True, add_book=False)
|
|
@@ -141,43 +210,69 @@ def mysteel_chemical_refresh(FilePath):
|
|
|
if os.path.exists(fileFullPath) and ".xlsx" in fileFullPath \
|
|
|
and fileFullPath.find("~$") < 0 \
|
|
|
and fileFullPath.find("template") < 0:
|
|
|
-
|
|
|
- ## 鼠标移动到左下角,开始搜索文件
|
|
|
- # moveX = 22
|
|
|
- # moveY = 1058
|
|
|
- # pyautogui.moveTo(moveX, moveY, 0.5)
|
|
|
- # pyautogui.click(moveX, moveY)
|
|
|
- # time.sleep(2)
|
|
|
- # pyautogui.typewrite(fileFullPath, 0.1)
|
|
|
- # # print("open file:" + fileFullPath)
|
|
|
- # # wb = app.books.open(fileFullPath)
|
|
|
- # pyautogui.keyDown('enter')
|
|
|
- # pyautogui.keyUp('enter')
|
|
|
- # pyautogui.keyDown('enter')
|
|
|
- # pyautogui.keyUp('enter')
|
|
|
-
|
|
|
- # 打开文件
|
|
|
- pythoncom.CoInitialize()
|
|
|
- # openStatus = os.system("start " + fileFullPath.strip())
|
|
|
- openStatus = os.system('start "" "{}"'.format(fileFullPath))
|
|
|
- # 在上面的代码中,使用双引号将文件名引用为一个整体,这可以确保 Windows 命令行正确解释带有空格的文件路径。os.system()函数将启动一个新的命令行窗口来运行命令,然后等待命令完成。在这种情况下,"start " 命令告诉 Windows 打开文件,并使用双引号将文件名引用为一个整体。
|
|
|
-
|
|
|
- # print("openStatus:", openStatus)
|
|
|
- if openStatus == 1:
|
|
|
- return False
|
|
|
+ # 获取文件名和扩展名
|
|
|
+ file_name, file_ext = os.path.splitext(os.path.basename(fileFullPath))
|
|
|
+ file_name_ext = file_name + file_ext
|
|
|
time.sleep(3)
|
|
|
|
|
|
+ try:
|
|
|
+
|
|
|
+ # 启动程序
|
|
|
+ code = exePath + " " + fileFullPath
|
|
|
+ # print(code)
|
|
|
+ autoit.run(code)
|
|
|
+ autoit.win_wait_active(file_name_ext, timeout=20) # 等待窗口激活
|
|
|
+ autoit.win_move(file_name_ext, 0, 0, 1024, 768)
|
|
|
+ # autoit.win_move(file_name_ext, 0, 0, 1920, 1080)
|
|
|
+
|
|
|
+ # print("监听成功了")
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print("监听", fileFullPath, "失败:", e)
|
|
|
+
|
|
|
+ ## 失败的话,截图记录下原因
|
|
|
+ screenshot = pyautogui.screenshot()
|
|
|
+ imgPath = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "_screenshot_img.png"
|
|
|
+ screenshot.save(imgPath)
|
|
|
+
|
|
|
+ hwnd = win32gui.GetForegroundWindow()
|
|
|
+ found_title = win32gui.GetWindowText(hwnd)
|
|
|
+ print("当前窗口名称:", found_title)
|
|
|
+ if found_title == "":
|
|
|
+ print("窗口未打开")
|
|
|
+ return
|
|
|
+
|
|
|
+ # 遍历异常名称列表去校验,如果匹配上了,那么就要退出excel并打开
|
|
|
+ for err_windows_name in err_windows_name_list:
|
|
|
+ if found_title.startswith(err_windows_name):
|
|
|
+ # 获取与窗口句柄关联的进程ID
|
|
|
+ process_id = win32process.GetWindowThreadProcessId(hwnd)[1]
|
|
|
+ # 根据进程ID获取进程对象并尝试优雅地终止进程
|
|
|
+ target_process = psutil.Process(process_id)
|
|
|
+ target_process.terminate()
|
|
|
+ print("可能是EXCEL崩溃导致,优雅退出EXCEL")
|
|
|
+ return
|
|
|
+
|
|
|
+ # 如果是office的,那么就是要将file_name_ext变更为 file_name;因为office没有后缀
|
|
|
+ if found_title.startswith(file_name_ext) == False:
|
|
|
+ print("当前窗口与excel不一致,当前窗口:", found_title, ";excel:", file_name_ext)
|
|
|
+ return
|
|
|
+ autoit.win_move_by_handle(hwnd, 0, 0, 1024, 768)
|
|
|
+
|
|
|
## 屏幕最大化
|
|
|
# open full screen
|
|
|
- hwnd = win32gui.GetForegroundWindow()
|
|
|
- win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
|
|
|
+ # hwnd = win32gui.GetForegroundWindow()
|
|
|
+ # win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
|
|
|
+ # time.sleep(1)
|
|
|
+
|
|
|
+ # 停留一秒,让屏幕改变到正常大小
|
|
|
time.sleep(1)
|
|
|
|
|
|
### 随机2-3次点击 单元格区域
|
|
|
r = random.randint(2, 3)
|
|
|
for i in range(r):
|
|
|
- pointX = random.randint(511, 1745)
|
|
|
- pointY = random.randint(282, 791)
|
|
|
+ pointX = random.randint(minPointX, maxPointX)
|
|
|
+ pointY = random.randint(minPointY, maxPointY)
|
|
|
print("随机点击", i + 1, "下")
|
|
|
pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
pyautogui.click()
|
|
@@ -187,29 +282,21 @@ def mysteel_chemical_refresh(FilePath):
|
|
|
time.sleep(r)
|
|
|
|
|
|
##点击 红桃3 按钮
|
|
|
- # pointX = 641
|
|
|
- # pointX = 590
|
|
|
- pointX = 521
|
|
|
- pointY = 42
|
|
|
- pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
+ pyautogui.moveTo(hongTao3PointX, hongTao3PointY, 0.5)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
##点击 数据刷新 按钮
|
|
|
- pointX = 199
|
|
|
- pointY = 78
|
|
|
- pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
+ pyautogui.moveTo(refreshButtonPointX, refreshButtonPointY, 0.5)
|
|
|
pyautogui.click()
|
|
|
time.sleep(1)
|
|
|
##点击 刷新工作簿 按钮
|
|
|
print("开始刷新了")
|
|
|
- pointX = 226
|
|
|
- pointY = 169
|
|
|
- pyautogui.moveTo(pointX, pointY, 0.5)
|
|
|
+ pyautogui.moveTo(refreshSheetPointX, refreshSheetPointY, 0.5)
|
|
|
pyautogui.click()
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
## 校验登录失效
|
|
|
- checkLoginInvalid()
|
|
|
+ # checkLoginInvalid()
|
|
|
|
|
|
## 校验重新登录
|
|
|
checkHongtaoLoginButton()
|
|
@@ -247,4 +334,6 @@ def mysteel_chemical_refresh(FilePath):
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
app = __hug__.http.server()
|
|
|
- run(app=app, reloader=True, port=7007)
|
|
|
+ # server="waitress" 这个是因为有些windows的主机名有中文,需要换个服务器适配器
|
|
|
+ run(app=app, host="0.0.0.0", reloader=True, port=7007, server="waitress")
|
|
|
+# http://127.0.0.1:7007/hongtao/refresh?FilePath=D:/eta/data/hongtao3_data/卓创数据统计.xlsx
|