完善tidevice逻辑
This commit is contained in:
8
.idea/workspace.xml
generated
8
.idea/workspace.xml
generated
@@ -6,9 +6,14 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="eceeff5e-51c1-459c-a911-d21ec090a423" name="Changes" comment="20250904-初步功能已完成">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Module/DeviceInfo.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/DeviceInfo.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Module/FlaskService.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/FlaskService.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Module/Main.py" beforeDir="false" afterPath="$PROJECT_DIR$/Module/Main.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Utils/LogManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/Utils/LogManager.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/script/ScriptManager.py" beforeDir="false" afterPath="$PROJECT_DIR$/script/ScriptManager.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/build-tidevice.bat" beforeDir="false" afterPath="$PROJECT_DIR$/build-tidevice.bat" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/build.bat" beforeDir="false" afterPath="$PROJECT_DIR$/build.bat" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/resources/iproxy/tidevice.exe" beforeDir="false" afterPath="$PROJECT_DIR$/resources/iproxy/tidevice.exe" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/tidevice_entry.py" beforeDir="false" afterPath="$PROJECT_DIR$/tidevice_entry.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -86,6 +91,7 @@
|
||||
<recent name="C:\Users\zhangkai\Desktop\20250916ios\iOSAI\resources" />
|
||||
</key>
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="E:\code\Python\iOSAi" />
|
||||
<recent name="E:\Code\python\iOSAI\resources" />
|
||||
<recent name="E:\Code\python\iOSAI" />
|
||||
</key>
|
||||
|
||||
@@ -6,11 +6,9 @@ import time
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional, List
|
||||
|
||||
import wda
|
||||
from tidevice import Usbmux, ConnectionType
|
||||
from tidevice._device import BaseDevice
|
||||
|
||||
from Entity.DeviceModel import DeviceModel
|
||||
from Module.FlaskSubprocessManager import FlaskSubprocessManager
|
||||
from Utils.LogManager import LogManager
|
||||
@@ -19,15 +17,12 @@ from Utils.LogManager import LogManager
|
||||
class DeviceInfo:
|
||||
def __init__(self):
|
||||
self._port = 9110
|
||||
self._models: Dict[str, DeviceModel] = {} # udid -> model
|
||||
self._procs: Dict[str, subprocess.Popen] = {} # udid -> iproxy proc
|
||||
self._models: Dict[str, DeviceModel] = {}
|
||||
self._procs: Dict[str, subprocess.Popen] = {}
|
||||
self._manager = FlaskSubprocessManager.get_instance()
|
||||
self._iproxy_path = self._find_iproxy()
|
||||
self._pool = ThreadPoolExecutor(max_workers=6)
|
||||
|
||||
# 可选:10 秒一次扫野进程
|
||||
threading.Thread(target=self._janitor, daemon=True).start()
|
||||
|
||||
# ---------------- 主循环 ----------------
|
||||
def listen(self):
|
||||
while True:
|
||||
@@ -89,13 +84,20 @@ class DeviceInfo:
|
||||
except Exception:
|
||||
return 828, 1792, 2.0
|
||||
|
||||
...
|
||||
# ---------------- 原来代码不变,只替换下面一个函数 ----------------
|
||||
def _start_iproxy(self, udid: str, port: int) -> Optional[subprocess.Popen]:
|
||||
try:
|
||||
# 隐藏窗口的核心参数
|
||||
kw = {"creationflags": subprocess.CREATE_NO_WINDOW}
|
||||
return subprocess.Popen(
|
||||
[self._iproxy_path, "-u", udid, str(port), "9100"],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
**kw
|
||||
)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def _kill(self, proc: Optional[subprocess.Popen]):
|
||||
@@ -124,16 +126,11 @@ class DeviceInfo:
|
||||
base = Path(__file__).resolve().parent.parent
|
||||
name = "iproxy.exe"
|
||||
path = base / "resources" / "iproxy" / name
|
||||
print(str(path))
|
||||
if path.is_file():
|
||||
return str(path)
|
||||
raise FileNotFoundError(f"iproxy 不存在: {path}")
|
||||
|
||||
# ---------------- janitor(扫野进程) ----------------
|
||||
def _janitor(self):
|
||||
while True:
|
||||
time.sleep(10)
|
||||
self._cleanup_orphan_iproxy()
|
||||
|
||||
# ------------ Windows 专用:列出所有 iproxy 命令行 ------------
|
||||
def _get_all_iproxy_cmdlines(self) -> List[str]:
|
||||
try:
|
||||
|
||||
@@ -2,12 +2,10 @@ import json
|
||||
import os
|
||||
import socket
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
from queue import Queue
|
||||
from typing import Any, Dict
|
||||
|
||||
from Entity.AnchorModel import AnchorModel
|
||||
from Utils.AiUtils import AiUtils
|
||||
from Utils.IOSAIStorage import IOSAIStorage
|
||||
from Utils.LogManager import LogManager
|
||||
@@ -19,7 +17,7 @@ from Entity.ResultData import ResultData
|
||||
from Utils.ControlUtils import ControlUtils
|
||||
from Utils.ThreadManager import ThreadManager
|
||||
from script.ScriptManager import ScriptManager
|
||||
from Entity.Variables import anchorList, prologueList, addModelToAnchorList, removeModelFromAnchorList
|
||||
from Entity.Variables import addModelToAnchorList
|
||||
import Entity.Variables as ev
|
||||
from Utils.JsonUtils import JsonUtils
|
||||
|
||||
@@ -268,7 +266,7 @@ def stopScript():
|
||||
udid = body.get("udid")
|
||||
LogManager.method_info(f"接口收到 /stopScript udid={udid}", method="task")
|
||||
code, msg = ThreadManager.stop(udid)
|
||||
return ResultData(code=code, data="", message=msg).toJson()
|
||||
return ResultData(code=code, data=[], message=msg).toJson()
|
||||
|
||||
|
||||
# 关注打招呼
|
||||
@@ -576,7 +574,7 @@ def delete_last_message():
|
||||
def stopAllTask():
|
||||
idList = request.get_json()
|
||||
code, msg = ThreadManager.batch_stop(idList)
|
||||
return ResultData(code, "", msg).toJson()
|
||||
return ResultData(code, [], msg).toJson()
|
||||
|
||||
|
||||
# @app.route("/killWda", methods=['POST'])
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import wda
|
||||
|
||||
import tidevice
|
||||
from Module.DeviceInfo import DeviceInfo
|
||||
from Module.FlaskSubprocessManager import FlaskSubprocessManager
|
||||
from Utils.DevDiskImageDeployer import DevDiskImageDeployer
|
||||
@@ -27,6 +31,27 @@ if "--role=flask" in sys.argv:
|
||||
# 项目入口
|
||||
if __name__ == "__main__":
|
||||
|
||||
wda.debug = True
|
||||
|
||||
# 1. 拿到打包后的临时目录
|
||||
base_dir = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# 2. 构造 resources/iproxy 绝对路径
|
||||
iproxy_dir = os.path.join(base_dir, 'resources', 'iproxy')
|
||||
|
||||
# 3. 如果目录存在就追加到 PATH
|
||||
if os.path.isdir(iproxy_dir):
|
||||
# Windows 用 ; 分隔,Linux/Mac 用 :
|
||||
sep = os.pathsep
|
||||
old_path = os.environ.get('PATH', '')
|
||||
# 避免重复追加
|
||||
if iproxy_dir not in old_path:
|
||||
os.environ['PATH'] = old_path + sep + iproxy_dir
|
||||
else:
|
||||
# 调试用,打包后可删掉
|
||||
print(f'warning: {iproxy_dir} not found', file=sys.stderr)
|
||||
|
||||
|
||||
# 添加iOS开发包到电脑上
|
||||
deployer = DevDiskImageDeployer(verbose=True)
|
||||
deployer.deploy_all()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,7 @@ def _force_utf8_everywhere():
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
_force_utf8_everywhere()
|
||||
# _force_utf8_everywhere()
|
||||
|
||||
class LogManager:
|
||||
"""
|
||||
|
||||
Binary file not shown.
@@ -7,3 +7,7 @@ pyinstaller -F -n tidevice ^
|
||||
--noconsole ^
|
||||
--add-data="C:\Users\milk\AppData\Local\Programs\Python\Python312\Lib\site-packages\tidevice;tidevice" ^
|
||||
tidevice_entry.py
|
||||
|
||||
@REM pyinstaller -F -n tidevice -noconsole ^
|
||||
@REM --collect-all tidevice ^
|
||||
@REM tidevice_entry.py
|
||||
80
build.bat
80
build.bat
@@ -1,18 +1,62 @@
|
||||
python -m nuitka "Module/Main.py" ^
|
||||
--standalone ^
|
||||
--msvc=latest ^
|
||||
--windows-console-mode=disable ^
|
||||
--output-filename=IOSAI ^
|
||||
--include-package=Module,Utils,Entity,script ^
|
||||
--include-module=flask ^
|
||||
--include-module=flask_cors ^
|
||||
--include-module=lxml ^
|
||||
--include-module=lxml.etree ^
|
||||
--include-module=requests ^
|
||||
--include-module=urllib3 ^
|
||||
--include-module=certifi ^
|
||||
--include-module=idna ^
|
||||
--include-data-dir="E:/code/Python/iOSAI/SupportFiles=SupportFiles" ^
|
||||
--include-data-dir="E:/code/Python/iOSAI/resources=resources" ^
|
||||
--include-data-files="E:/code/Python/iOSAI/resources/iproxy/*=resources/iproxy/" ^
|
||||
--windows-icon-from-ico="E:/code/Python/iOSAI/resources/icon.ico"
|
||||
@REM python -m nuitka "Module/Main.py" ^
|
||||
@REM --standalone ^
|
||||
@REM --msvc=latest ^
|
||||
@REM --windows-console-mode=disable ^
|
||||
@REM --output-filename=IOSAI ^
|
||||
@REM --include-package=Module,Utils,Entity,script ^
|
||||
@REM --include-module=flask ^
|
||||
@REM --include-module=flask_cors ^
|
||||
@REM --include-module=lxml ^
|
||||
@REM --include-module=lxml.etree ^
|
||||
@REM --include-module=requests ^
|
||||
@REM --include-module=urllib3 ^
|
||||
@REM --include-module=certifi ^
|
||||
@REM --include-module=idna ^
|
||||
@REM --include-data-files="E:/code/Python/iOSAI/.venv/Scripts/tidevice.exe=tidevice.exe" ^
|
||||
@REM --include-data-dir="E:/code/Python/iOSAI/.venv/Scripts=Scripts" ^
|
||||
@REM --include-data-dir="E:/code/Python/iOSAI/SupportFiles=SupportFiles" ^
|
||||
@REM --include-data-dir="E:/code/Python/iOSAI/resources=resources" ^
|
||||
@REM --include-data-files="E:/code/Python/iOSAI/resources/iproxy/*=resources/iproxy/" ^
|
||||
@REM --windows-icon-from-ico="E:/code/Python/iOSAI/resources/icon.ico"
|
||||
|
||||
|
||||
|
||||
@REM python -m nuitka "Module/Main.py" ^
|
||||
@REM --standalone ^
|
||||
@REM --msvc=latest ^
|
||||
@REM --windows-console-mode=force ^
|
||||
@REM --output-filename=IOSAI ^
|
||||
@REM --include-package=Module,Utils,Entity,script ^
|
||||
@REM --include-module=flask ^
|
||||
@REM --include-module=wda ^
|
||||
@REM --include-module=flask_cors ^
|
||||
@REM --include-module=lxml ^
|
||||
@REM --include-module=lxml.etree ^
|
||||
@REM --include-module=requests ^
|
||||
@REM --include-module=urllib3 ^
|
||||
@REM --include-module=certifi ^
|
||||
@REM --include-module=idna ^
|
||||
@REM --include-module=setuptools ^
|
||||
@REM --include-module=tidevice ^
|
||||
@REM --include-data-dir=resources=resources ^
|
||||
@REM --include-data-dir=SupportFiles=SupportFiles ^
|
||||
@REM --include-data-files="E:/code/Python/iOSAi/resources/iproxy/*=resources/iproxy/" ^
|
||||
@REM --include-data-files=resources/icon.ico=resources/icon.ico ^
|
||||
@REM --jobs=20 ^
|
||||
@REM --windows-icon-from-ico=resources/icon.ico
|
||||
|
||||
|
||||
python -m nuitka Module\Main.py ^
|
||||
--standalone ^
|
||||
--msvc=latest ^
|
||||
--windows-console-mode=force ^
|
||||
--output-filename=IOSAI ^
|
||||
--include-package=Module,Utils,Entity,script ^
|
||||
--include-module=flask,wda,flask_cors,lxml,lxml.etree,requests,urllib3,certifi,idna,setuptools,tidevice ^
|
||||
--include-data-dir=resources=resources ^
|
||||
--include-data-dir=SupportFiles=SupportFiles ^
|
||||
--include-data-files="E:/code/Python/iOSAi/resources/iproxy/*=resources/iproxy/" ^
|
||||
--include-data-files=resources/icon.ico=resources/icon.ico ^
|
||||
--jobs=20 ^
|
||||
--windows-icon-from-ico=resources/icon.ico
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,16 +1,37 @@
|
||||
# import sys, traceback, os
|
||||
# from tidevice.__main__ import main
|
||||
#
|
||||
# import sys, os
|
||||
# with open(os.path.join(os.path.dirname(sys.executable), '_entry_log.txt'), 'w') as f:
|
||||
# f.write('entry reached\nargs=%r\n' % sys.argv)
|
||||
#
|
||||
# if hasattr(sys, 'frozen') and sys.executable.endswith('.exe'):
|
||||
# # 打包后且无控制台时,把标准流扔掉
|
||||
# sys.stdout = sys.stderr = open(os.devnull, 'w', encoding='utf-8')
|
||||
#
|
||||
# if __name__ == "__main__":
|
||||
# try:
|
||||
# main()
|
||||
# except Exception:
|
||||
# # 把 traceback 写到日志文件,但**不输出到控制台**
|
||||
# with open(os.path.expanduser("~/tidevice_crash.log"), "a", encoding="utf-8") as f:
|
||||
# traceback.print_exc(file=f)
|
||||
# # 静默退出,返回码 1
|
||||
# sys.exit(1)
|
||||
|
||||
|
||||
import sys, traceback, os
|
||||
from tidevice.__main__ import main
|
||||
|
||||
if hasattr(sys, 'frozen') and sys.executable.endswith('.exe'):
|
||||
# 打包后且无控制台时,把标准流扔掉
|
||||
sys.stdout = sys.stderr = open(os.devnull, 'w', encoding='utf-8')
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
# 把 traceback 写到日志文件,但**不输出到控制台**
|
||||
with open(os.path.expanduser("~/tidevice_crash.log"), "a", encoding="utf-8") as f:
|
||||
except SystemExit as se: # 允许正常 exit(code) 继续生效
|
||||
raise
|
||||
except Exception: # 真正异常时才写日志
|
||||
crash_log = os.path.expanduser("~/tidevice_crash.log")
|
||||
with open(crash_log, "a", encoding="utf-8") as f:
|
||||
f.write("----- tidevice exe crash -----\n")
|
||||
traceback.print_exc(file=f)
|
||||
# 静默退出,返回码 1
|
||||
# 如果想让用户知道崩溃了,可以返回非 0
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user