Compare commits

...

9 Commits

Author SHA1 Message Date
20bd7163a9 修改文件登录密钥 2026-03-12 17:01:36 +08:00
febff22f3b 到轨迹脚本 2026-03-02 18:28:50 +08:00
c60ccc75b8 结合自动到轨迹 2026-03-02 18:26:12 +08:00
560cc083a0 修改重启驱动时设置手机 2026-02-12 09:55:59 +08:00
5571cd0a33 修改截图执行时间。一旦is_ok=1且为true就开始截图。 2026-02-11 12:20:35 +08:00
9f23776d5a 新打包程序 2026-02-10 17:58:45 +08:00
d83ca7557e 修改获取截图时间文件路径为D:\\uploadInfo\\Logs\\ 2026-02-10 17:49:56 +08:00
119bb845b4 截图不全改回true 2026-02-10 17:39:58 +08:00
6274c83dd5 修改截图保存文件夹 2026-02-10 14:41:13 +08:00
51 changed files with 71619 additions and 735 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,64 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean this module is required for running your program. Python and
Python 3rd-party packages include a lot of conditional or optional modules. For
example the module 'ntpath' only exists on Windows, whereas the module
'posixpath' only exists on Posix systems.
Types if import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), netrc (delayed, conditional), getpass (delayed)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
missing module named fcntl - imported by subprocess (optional)
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named termios - imported by getpass (optional)
missing module named _sha512 - imported by random (optional)
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named posix - imported by posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional), os (conditional, optional)
missing module named resource - imported by posix (top-level)
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named pyimod02_importers - imported by C:\Program Files\Python312\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
missing module named collections.Callable - imported by collections (optional), socks (optional)
missing module named simplejson - imported by requests.compat (conditional, optional)
missing module named dummy_threading - imported by requests.cookies (optional)
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
missing module named annotationlib - imported by typing_extensions (conditional)
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named compression - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
missing module named h2 - imported by urllib3.http2.connection (top-level)
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named win_inet_pton - imported by socks (conditional, optional)
missing module named cryptography - imported by urllib3.contrib.pyopenssl (top-level), requests (conditional, optional)
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl (delayed, optional)
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named wsaccel - imported by websocket._utils (optional)
missing module named 'python_socks.sync' - imported by websocket._http (optional)
missing module named 'python_socks._types' - imported by websocket._http (optional)
missing module named python_socks - imported by websocket._http (optional)
missing module named 'wsaccel.xormask' - imported by websocket._abnf (optional)
missing module named _winreg - imported by platform (delayed, optional), selenium.webdriver.firefox.firefox_binary (delayed, optional)
missing module named vms_lib - imported by platform (delayed, optional)
missing module named 'java.lang' - imported by platform (delayed, optional)
missing module named java - imported by platform (delayed)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,432 @@
('D:\\Projects\\cjgc_screenshot\\dist\\自动导轨迹.exe',
True,
False,
False,
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-console.ico',
None,
False,
False,
b'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<assembly xmlns='
b'"urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\n <trustInfo x'
b'mlns="urn:schemas-microsoft-com:asm.v3">\n <security>\n <requested'
b'Privileges>\n <requestedExecutionLevel level="asInvoker" uiAccess='
b'"false"/>\n </requestedPrivileges>\n </security>\n </trustInfo>\n '
b'<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">\n <'
b'application>\n <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f'
b'0}"/>\n <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>\n '
b' <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>\n <s'
b'upportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>\n <supporte'
b'dOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>\n </application>\n <'
b'/compatibility>\n <application xmlns="urn:schemas-microsoft-com:asm.v3">'
b'\n <windowsSettings>\n <longPathAware xmlns="http://schemas.micros'
b'oft.com/SMI/2016/WindowsSettings">true</longPathAware>\n </windowsSett'
b'ings>\n </application>\n <dependency>\n <dependentAssembly>\n <ass'
b'emblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version='
b'"6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" langua'
b'ge="*"/>\n </dependentAssembly>\n </dependency>\n</assembly>',
True,
False,
None,
None,
None,
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\自动导轨迹.pkg',
[('pyi-contents-directory _internal', '', 'OPTION'),
('PYZ-00.pyz',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\PYZ-00.pyz',
'PYZ'),
('struct',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\struct.pyc',
'PYMODULE'),
('pyimod01_archive',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod01_archive.pyc',
'PYMODULE'),
('pyimod02_importers',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod02_importers.pyc',
'PYMODULE'),
('pyimod03_ctypes',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod03_ctypes.pyc',
'PYMODULE'),
('pyimod04_pywin32',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod04_pywin32.pyc',
'PYMODULE'),
('pyiboot01_bootstrap',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
'PYSOURCE'),
('pyi_rth_inspect',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('pyi_rth_pywintypes',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pywintypes.py',
'PYSOURCE'),
('pyi_rth_pythoncom',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pythoncom.py',
'PYSOURCE'),
('pyi_rth_pkgutil',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py',
'PYSOURCE'),
('pyi_rth_multiprocessing',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_multiprocessing.py',
'PYSOURCE'),
('get_line_code',
'D:\\Projects\\cjgc_screenshot\\get_line_code.py',
'PYSOURCE'),
('python312.dll', 'C:\\Program Files\\Python312\\python312.dll', 'BINARY'),
('pywin32_system32\\pywintypes312.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pywintypes312.dll',
'BINARY'),
('pywin32_system32\\pythoncom312.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pythoncom312.dll',
'BINARY'),
('numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
'BINARY'),
('numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
'BINARY'),
('_multiprocessing.pyd',
'C:\\Program Files\\Python312\\DLLs\\_multiprocessing.pyd',
'EXTENSION'),
('pyexpat.pyd',
'C:\\Program Files\\Python312\\DLLs\\pyexpat.pyd',
'EXTENSION'),
('_ssl.pyd', 'C:\\Program Files\\Python312\\DLLs\\_ssl.pyd', 'EXTENSION'),
('_hashlib.pyd',
'C:\\Program Files\\Python312\\DLLs\\_hashlib.pyd',
'EXTENSION'),
('unicodedata.pyd',
'C:\\Program Files\\Python312\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('_decimal.pyd',
'C:\\Program Files\\Python312\\DLLs\\_decimal.pyd',
'EXTENSION'),
('select.pyd', 'C:\\Program Files\\Python312\\DLLs\\select.pyd', 'EXTENSION'),
('_lzma.pyd', 'C:\\Program Files\\Python312\\DLLs\\_lzma.pyd', 'EXTENSION'),
('_bz2.pyd', 'C:\\Program Files\\Python312\\DLLs\\_bz2.pyd', 'EXTENSION'),
('_ctypes.pyd',
'C:\\Program Files\\Python312\\DLLs\\_ctypes.pyd',
'EXTENSION'),
('_queue.pyd', 'C:\\Program Files\\Python312\\DLLs\\_queue.pyd', 'EXTENSION'),
('Pythonwin\\win32ui.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\win32ui.pyd',
'EXTENSION'),
('win32\\win32trace.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32trace.pyd',
'EXTENSION'),
('win32\\_win32sysloader.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\win32\\_win32sysloader.pyd',
'EXTENSION'),
('numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
'EXTENSION'),
('win32\\win32pdh.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32pdh.pyd',
'EXTENSION'),
('_overlapped.pyd',
'C:\\Program Files\\Python312\\DLLs\\_overlapped.pyd',
'EXTENSION'),
('_asyncio.pyd',
'C:\\Program Files\\Python312\\DLLs\\_asyncio.pyd',
'EXTENSION'),
('numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
'EXTENSION'),
('charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
'EXTENSION'),
('charset_normalizer\\md.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md.cp312-win_amd64.pyd',
'EXTENSION'),
('_socket.pyd',
'C:\\Program Files\\Python312\\DLLs\\_socket.pyd',
'EXTENSION'),
('numpy\\random\\mtrand.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\mtrand.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_sfc64.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_sfc64.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_philox.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_philox.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_pcg64.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_pcg64.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_mt19937.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_mt19937.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\bit_generator.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\bit_generator.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_generator.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_generator.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_common.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_common.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
'EXTENSION'),
('_wmi.pyd', 'C:\\Program Files\\Python312\\DLLs\\_wmi.pyd', 'EXTENSION'),
('PIL\\_webp.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_webp.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_imagingtk.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingtk.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_avif.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_avif.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_imagingcms.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingcms.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_imagingmath.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingmath.cp312-win_amd64.pyd',
'EXTENSION'),
('_elementtree.pyd',
'C:\\Program Files\\Python312\\DLLs\\_elementtree.pyd',
'EXTENSION'),
('PIL\\_imaging.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imaging.cp312-win_amd64.pyd',
'EXTENSION'),
('win32\\win32file.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32file.pyd',
'EXTENSION'),
('win32\\win32event.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32event.pyd',
'EXTENSION'),
('win32\\win32gui.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32gui.pyd',
'EXTENSION'),
('win32\\win32api.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32api.pyd',
'EXTENSION'),
('win32\\win32process.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32process.pyd',
'EXTENSION'),
('psutil\\_psutil_windows.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\psutil\\_psutil_windows.pyd',
'EXTENSION'),
('api-ms-win-crt-time-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-time-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-environment-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-environment-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-math-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-math-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-heap-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-heap-l1-1-0.dll',
'BINARY'),
('VCRUNTIME140.dll',
'C:\\Program Files\\Python312\\VCRUNTIME140.dll',
'BINARY'),
('api-ms-win-crt-filesystem-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-filesystem-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-stdio-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-stdio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-convert-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-convert-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-locale-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-locale-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-process-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-process-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-conio-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-conio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-runtime-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-runtime-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-string-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-string-l1-1-0.dll',
'BINARY'),
('VCRUNTIME140_1.dll',
'C:\\Program Files\\Python312\\VCRUNTIME140_1.dll',
'BINARY'),
('api-ms-win-crt-utility-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-utility-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-private-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-private-l1-1-0.dll',
'BINARY'),
('libssl-3.dll',
'C:\\Program Files\\Python312\\DLLs\\libssl-3.dll',
'BINARY'),
('libcrypto-3.dll',
'C:\\Program Files\\Python312\\DLLs\\libcrypto-3.dll',
'BINARY'),
('libffi-8.dll',
'C:\\Program Files\\Python312\\DLLs\\libffi-8.dll',
'BINARY'),
('Pythonwin\\mfc140u.dll',
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\mfc140u.dll',
'BINARY'),
('python3.dll', 'C:\\Program Files\\Python312\\python3.dll', 'BINARY'),
('ucrtbase.dll', 'D:\\Resource\\JDK\\JavaJDK17\\bin\\ucrtbase.dll', 'BINARY'),
('api-ms-win-crt-multibyte-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-multibyte-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-debug-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-debug-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-timezone-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-timezone-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-errorhandling-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-errorhandling-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-console-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-console-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-libraryloader-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-libraryloader-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-string-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-string-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-datetime-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-datetime-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-2-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-interlocked-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-interlocked-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l2-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l2-1-0.dll',
'BINARY'),
('api-ms-win-core-sysinfo-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-sysinfo-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-profile-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-profile-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-namedpipe-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-namedpipe-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-heap-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-heap-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processenvironment-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processenvironment-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-handle-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-handle-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-1.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-1.dll',
'BINARY'),
('api-ms-win-core-synch-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-rtlsupport-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-rtlsupport-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-memory-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-memory-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-util-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-util-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-localization-l1-2-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-localization-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-synch-l1-2-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-2-0.dll',
'BINARY'),
('certifi\\py.typed',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\py.typed',
'DATA'),
('certifi\\cacert.pem',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\cacert.pem',
'DATA'),
('numpy-2.2.4.dist-info\\METADATA',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\METADATA',
'DATA'),
('numpy-2.2.4.dist-info\\DELVEWHEEL',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\DELVEWHEEL',
'DATA'),
('numpy-2.2.4.dist-info\\RECORD',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\RECORD',
'DATA'),
('numpy-2.2.4.dist-info\\INSTALLER',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\INSTALLER',
'DATA'),
('numpy-2.2.4.dist-info\\REQUESTED',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\REQUESTED',
'DATA'),
('numpy-2.2.4.dist-info\\LICENSE.txt',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\LICENSE.txt',
'DATA'),
('numpy-2.2.4.dist-info\\WHEEL',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\WHEEL',
'DATA'),
('numpy-2.2.4.dist-info\\entry_points.txt',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\entry_points.txt',
'DATA'),
('base_library.zip',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\base_library.zip',
'DATA')],
[],
False,
False,
1773036587,
[('run.exe',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\bootloader\\Windows-64bit-intel\\run.exe',
'EXECUTABLE')],
'C:\\Program Files\\Python312\\python312.dll')

View File

@@ -0,0 +1,408 @@
('D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\自动导轨迹.pkg',
{'BINARY': True,
'DATA': True,
'EXECUTABLE': True,
'EXTENSION': True,
'PYMODULE': True,
'PYSOURCE': True,
'PYZ': False,
'SPLASH': True,
'SYMLINK': False},
[('pyi-contents-directory _internal', '', 'OPTION'),
('PYZ-00.pyz',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\PYZ-00.pyz',
'PYZ'),
('struct',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\struct.pyc',
'PYMODULE'),
('pyimod01_archive',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod01_archive.pyc',
'PYMODULE'),
('pyimod02_importers',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod02_importers.pyc',
'PYMODULE'),
('pyimod03_ctypes',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod03_ctypes.pyc',
'PYMODULE'),
('pyimod04_pywin32',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\localpycs\\pyimod04_pywin32.pyc',
'PYMODULE'),
('pyiboot01_bootstrap',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
'PYSOURCE'),
('pyi_rth_inspect',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('pyi_rth_pywintypes',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pywintypes.py',
'PYSOURCE'),
('pyi_rth_pythoncom',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\rthooks\\pyi_rth_pythoncom.py',
'PYSOURCE'),
('pyi_rth_pkgutil',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_pkgutil.py',
'PYSOURCE'),
('pyi_rth_multiprocessing',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_multiprocessing.py',
'PYSOURCE'),
('get_line_code',
'D:\\Projects\\cjgc_screenshot\\get_line_code.py',
'PYSOURCE'),
('python312.dll', 'C:\\Program Files\\Python312\\python312.dll', 'BINARY'),
('pywin32_system32\\pywintypes312.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pywintypes312.dll',
'BINARY'),
('pywin32_system32\\pythoncom312.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\pywin32_system32\\pythoncom312.dll',
'BINARY'),
('numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\libscipy_openblas64_-43e11ff0749b8cbe0a615c9cf6737e0e.dll',
'BINARY'),
('numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy.libs\\msvcp140-263139962577ecda4cd9469ca360a746.dll',
'BINARY'),
('_multiprocessing.pyd',
'C:\\Program Files\\Python312\\DLLs\\_multiprocessing.pyd',
'EXTENSION'),
('pyexpat.pyd',
'C:\\Program Files\\Python312\\DLLs\\pyexpat.pyd',
'EXTENSION'),
('_ssl.pyd', 'C:\\Program Files\\Python312\\DLLs\\_ssl.pyd', 'EXTENSION'),
('_hashlib.pyd',
'C:\\Program Files\\Python312\\DLLs\\_hashlib.pyd',
'EXTENSION'),
('unicodedata.pyd',
'C:\\Program Files\\Python312\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('_decimal.pyd',
'C:\\Program Files\\Python312\\DLLs\\_decimal.pyd',
'EXTENSION'),
('select.pyd', 'C:\\Program Files\\Python312\\DLLs\\select.pyd', 'EXTENSION'),
('_lzma.pyd', 'C:\\Program Files\\Python312\\DLLs\\_lzma.pyd', 'EXTENSION'),
('_bz2.pyd', 'C:\\Program Files\\Python312\\DLLs\\_bz2.pyd', 'EXTENSION'),
('_ctypes.pyd',
'C:\\Program Files\\Python312\\DLLs\\_ctypes.pyd',
'EXTENSION'),
('_queue.pyd', 'C:\\Program Files\\Python312\\DLLs\\_queue.pyd', 'EXTENSION'),
('Pythonwin\\win32ui.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\win32ui.pyd',
'EXTENSION'),
('win32\\win32trace.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32trace.pyd',
'EXTENSION'),
('win32\\_win32sysloader.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\win32\\_win32sysloader.pyd',
'EXTENSION'),
('numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_umath.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\linalg\\_umath_linalg.cp312-win_amd64.pyd',
'EXTENSION'),
('win32\\win32pdh.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32pdh.pyd',
'EXTENSION'),
('_overlapped.pyd',
'C:\\Program Files\\Python312\\DLLs\\_overlapped.pyd',
'EXTENSION'),
('_asyncio.pyd',
'C:\\Program Files\\Python312\\DLLs\\_asyncio.pyd',
'EXTENSION'),
('numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\_core\\_multiarray_tests.cp312-win_amd64.pyd',
'EXTENSION'),
('charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md__mypyc.cp312-win_amd64.pyd',
'EXTENSION'),
('charset_normalizer\\md.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\charset_normalizer\\md.cp312-win_amd64.pyd',
'EXTENSION'),
('_socket.pyd',
'C:\\Program Files\\Python312\\DLLs\\_socket.pyd',
'EXTENSION'),
('numpy\\random\\mtrand.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\mtrand.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_sfc64.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_sfc64.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_philox.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_philox.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_pcg64.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_pcg64.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_mt19937.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_mt19937.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\bit_generator.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\bit_generator.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_generator.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_generator.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_bounded_integers.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\random\\_common.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\random\\_common.cp312-win_amd64.pyd',
'EXTENSION'),
('numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy\\fft\\_pocketfft_umath.cp312-win_amd64.pyd',
'EXTENSION'),
('_wmi.pyd', 'C:\\Program Files\\Python312\\DLLs\\_wmi.pyd', 'EXTENSION'),
('PIL\\_webp.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_webp.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_imagingtk.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingtk.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_avif.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_avif.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_imagingcms.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingcms.cp312-win_amd64.pyd',
'EXTENSION'),
('PIL\\_imagingmath.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imagingmath.cp312-win_amd64.pyd',
'EXTENSION'),
('_elementtree.pyd',
'C:\\Program Files\\Python312\\DLLs\\_elementtree.pyd',
'EXTENSION'),
('PIL\\_imaging.cp312-win_amd64.pyd',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\PIL\\_imaging.cp312-win_amd64.pyd',
'EXTENSION'),
('win32\\win32file.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32file.pyd',
'EXTENSION'),
('win32\\win32event.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32event.pyd',
'EXTENSION'),
('win32\\win32gui.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32gui.pyd',
'EXTENSION'),
('win32\\win32api.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32api.pyd',
'EXTENSION'),
('win32\\win32process.pyd',
'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\win32process.pyd',
'EXTENSION'),
('psutil\\_psutil_windows.pyd',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\psutil\\_psutil_windows.pyd',
'EXTENSION'),
('api-ms-win-crt-time-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-time-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-environment-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-environment-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-math-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-math-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-heap-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-heap-l1-1-0.dll',
'BINARY'),
('VCRUNTIME140.dll',
'C:\\Program Files\\Python312\\VCRUNTIME140.dll',
'BINARY'),
('api-ms-win-crt-filesystem-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-filesystem-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-stdio-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-stdio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-convert-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-convert-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-locale-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-locale-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-process-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-process-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-conio-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-conio-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-runtime-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-runtime-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-string-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-string-l1-1-0.dll',
'BINARY'),
('VCRUNTIME140_1.dll',
'C:\\Program Files\\Python312\\VCRUNTIME140_1.dll',
'BINARY'),
('api-ms-win-crt-utility-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-utility-l1-1-0.dll',
'BINARY'),
('api-ms-win-crt-private-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-private-l1-1-0.dll',
'BINARY'),
('libssl-3.dll',
'C:\\Program Files\\Python312\\DLLs\\libssl-3.dll',
'BINARY'),
('libcrypto-3.dll',
'C:\\Program Files\\Python312\\DLLs\\libcrypto-3.dll',
'BINARY'),
('libffi-8.dll',
'C:\\Program Files\\Python312\\DLLs\\libffi-8.dll',
'BINARY'),
('Pythonwin\\mfc140u.dll',
'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin\\mfc140u.dll',
'BINARY'),
('python3.dll', 'C:\\Program Files\\Python312\\python3.dll', 'BINARY'),
('ucrtbase.dll', 'D:\\Resource\\JDK\\JavaJDK17\\bin\\ucrtbase.dll', 'BINARY'),
('api-ms-win-crt-multibyte-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-crt-multibyte-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-debug-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-debug-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-timezone-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-timezone-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-errorhandling-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-errorhandling-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-console-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-console-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-libraryloader-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-libraryloader-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-string-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-string-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-datetime-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-datetime-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-2-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-interlocked-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-interlocked-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-file-l2-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-file-l2-1-0.dll',
'BINARY'),
('api-ms-win-core-sysinfo-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-sysinfo-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-profile-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-profile-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-namedpipe-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-namedpipe-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-heap-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-heap-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processenvironment-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processenvironment-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-handle-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-handle-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-processthreads-l1-1-1.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-processthreads-l1-1-1.dll',
'BINARY'),
('api-ms-win-core-synch-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-rtlsupport-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-rtlsupport-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-memory-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-memory-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-util-l1-1-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-util-l1-1-0.dll',
'BINARY'),
('api-ms-win-core-localization-l1-2-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-localization-l1-2-0.dll',
'BINARY'),
('api-ms-win-core-synch-l1-2-0.dll',
'D:\\Resource\\JDK\\JavaJDK17\\bin\\api-ms-win-core-synch-l1-2-0.dll',
'BINARY'),
('certifi\\py.typed',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\py.typed',
'DATA'),
('certifi\\cacert.pem',
'C:\\Users\\ADMIN\\AppData\\Roaming\\Python\\Python312\\site-packages\\certifi\\cacert.pem',
'DATA'),
('numpy-2.2.4.dist-info\\METADATA',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\METADATA',
'DATA'),
('numpy-2.2.4.dist-info\\DELVEWHEEL',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\DELVEWHEEL',
'DATA'),
('numpy-2.2.4.dist-info\\RECORD',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\RECORD',
'DATA'),
('numpy-2.2.4.dist-info\\INSTALLER',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\INSTALLER',
'DATA'),
('numpy-2.2.4.dist-info\\REQUESTED',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\REQUESTED',
'DATA'),
('numpy-2.2.4.dist-info\\LICENSE.txt',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\LICENSE.txt',
'DATA'),
('numpy-2.2.4.dist-info\\WHEEL',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\WHEEL',
'DATA'),
('numpy-2.2.4.dist-info\\entry_points.txt',
'C:\\Program '
'Files\\Python312\\Lib\\site-packages\\numpy-2.2.4.dist-info\\entry_points.txt',
'DATA'),
('base_library.zip',
'D:\\Projects\\cjgc_screenshot\\build\\自动导轨迹\\base_library.zip',
'DATA')],
'python312.dll',
False,
False,
False,
[],
None,
None,
None)

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,259 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean this module is required for running your program. Python and
Python 3rd-party packages include a lot of conditional or optional modules. For
example the module 'ntpath' only exists on Windows, whereas the module
'posixpath' only exists on Posix systems.
Types if import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named termios - imported by getpass (optional), tty (top-level)
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), psutil (optional), netrc (delayed, conditional), getpass (delayed), http.server (delayed, optional)
missing module named _sha512 - imported by random (optional)
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named posix - imported by os (conditional, optional), shutil (conditional), importlib._bootstrap_external (conditional), posixpath (optional)
missing module named resource - imported by posix (top-level)
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
missing module named ctypes._FuncPointer - imported by ctypes (conditional), comtypes._vtbl (conditional)
missing module named ctypes._CDataType - imported by ctypes (conditional), comtypes._memberspec (conditional), comtypes.automation (conditional)
missing module named ctypes._CArgObject - imported by ctypes (conditional), comtypes._memberspec (conditional), comtypes.automation (conditional), comtypes._comobject (conditional), comtypes.messageloop (conditional), comtypes.connectionpoints (conditional)
missing module named ctypes._CData - imported by ctypes (conditional), comtypes (conditional)
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named pyimod02_importers - imported by C:\Program Files\Python312\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
missing module named collections.Callable - imported by collections (optional), socks (optional)
missing module named 'win32com.gen_py' - imported by win32com (conditional, optional)
missing module named numpy._core.void - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.vecmat - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ushort - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.unsignedinteger - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ulonglong - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ulong - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.uintp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.uintc - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.uint64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.uint32 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.uint16 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.uint - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ubyte - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.trunc - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.true_divide - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.timedelta64 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.tanh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.tan - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.subtract - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.str_ - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.square - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.spacing - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.sinh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.signedinteger - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.short - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.rint - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.right_shift - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.remainder - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.radians - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.rad2deg - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.power - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.positive - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.pi - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.not_equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.negative - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.modf - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.mod - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.minimum - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.maximum - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.matvec - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.longdouble - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.long - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_xor - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_or - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_not - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_and - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logaddexp2 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logaddexp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.log2 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.log1p - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.log - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.less_equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.less - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.left_shift - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ldexp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.lcm - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.integer - imported by numpy._core (conditional), numpy (conditional), numpy.fft._helper (top-level)
missing module named numpy._core.int8 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.int64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.int32 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.int16 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.hypot - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.heaviside - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.half - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.greater_equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.greater - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.gcd - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.frompyfunc - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.frexp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fmod - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fmin - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fmax - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.floor_divide - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.floor - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.floating - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.float_power - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.float16 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fabs - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.expm1 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.exp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.euler_gamma - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.e - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.divmod - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.degrees - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.deg2rad - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.datetime64 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.cosh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.cos - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.copysign - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.conjugate - imported by numpy._core (conditional), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.conj - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.complex64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.clongdouble - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.character - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ceil - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.cbrt - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bytes_ - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.byte - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bool_ - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_xor - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_or - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_count - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_and - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arctanh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arctan2 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arctan - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arcsinh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arcsin - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arccosh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arccos - imported by numpy._core (conditional), numpy (conditional)
missing module named threadpoolctl - imported by numpy.lib._utils_impl (delayed, optional)
missing module named readline - imported by cmd (delayed, conditional, optional), code (delayed, conditional, optional), pdb (delayed, optional)
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
missing module named _dummy_thread - imported by numpy._core.arrayprint (optional)
missing module named numpy._core.ones - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.hstack - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.atleast_1d - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.atleast_3d - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
missing module named numpy._core.vstack - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
missing module named numpy._core.linspace - imported by numpy._core (top-level), numpy.lib._index_tricks_impl (top-level), numpy (conditional)
missing module named numpy._core.result_type - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.number - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.max - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.array2string - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.signbit - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.isscalar - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.isnat - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
missing module named numpy._core.array_repr - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
missing module named numpy._core.arange - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
missing module named numpy._core.float32 - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.vecdot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.matrix_transpose - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.matmul - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.tensordot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.outer - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.cross - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.trace - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.diagonal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.reciprocal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.sort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.argsort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.sign - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.isnan - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.count_nonzero - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.divide - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.swapaxes - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.object_ - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.asanyarray - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.intp - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.atleast_2d - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.prod - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.amax - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.amin - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.moveaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.errstate - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.finfo - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.isfinite - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.sum - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.sqrt - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.multiply - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.add - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.dot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.inf - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.all - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.newaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.complexfloating - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.inexact - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.cdouble - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.csingle - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.double - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.single - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.intc - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.empty_like - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.empty - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
missing module named numpy._core.zeros - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.array - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.iinfo - imported by numpy._core (top-level), numpy.lib._twodim_base_impl (top-level), numpy (conditional)
missing module named numpy._core.transpose - imported by numpy._core (top-level), numpy.lib._function_base_impl (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.ndarray - imported by numpy._core (top-level), numpy.lib._utils_impl (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
missing module named numpy._core.asarray - imported by numpy._core (top-level), numpy.lib._array_utils_impl (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level), numpy.fft._helper (top-level)
missing module named 'numpy_distutils.cpuinfo' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
missing module named 'numpy_distutils.fcompiler' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
missing module named 'numpy_distutils.command' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
missing module named numpy_distutils - imported by numpy.f2py.diagnose (delayed, optional)
missing module named annotationlib - imported by typing_extensions (conditional)
missing module named yaml - imported by numpy.__config__ (delayed)
missing module named numpy._distributor_init_local - imported by numpy (optional), numpy._distributor_init (optional)
missing module named vms_lib - imported by platform (delayed, optional)
missing module named 'java.lang' - imported by platform (delayed, optional)
missing module named java - imported by platform (delayed)
missing module named _winreg - imported by platform (delayed, optional)
missing module named logger - imported by pywinauto.actionlogger (optional)
missing module named 'Xlib.ext' - imported by pywinauto.linux.keyboard (top-level), pywinauto.mouse (conditional)
missing module named Xlib - imported by pywinauto.linux.keyboard (top-level), pywinauto.mouse (conditional)
missing module named 'Xlib.display' - imported by pywinauto.mouse (conditional)
missing module named 'Xlib.XK' - imported by pywinauto.linux.keyboard (top-level)
missing module named olefile - imported by PIL.FpxImagePlugin (top-level), PIL.MicImagePlugin (top-level)
missing module named defusedxml - imported by PIL.Image (optional)
missing module named extra_tests - imported by pywinauto.tests (delayed, optional)
missing module named StringIO - imported by six (conditional)
missing module named simplejson - imported by requests.compat (conditional, optional)
missing module named dummy_threading - imported by requests.cookies (optional)
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named compression - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
missing module named h2 - imported by urllib3.http2.connection (top-level)
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named win_inet_pton - imported by socks (conditional, optional)
missing module named cryptography - imported by urllib3.contrib.pyopenssl (top-level), requests (conditional, optional)
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl (delayed, optional)
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named fcntl - imported by subprocess (optional)

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,347 +0,0 @@
import subprocess
import re
import time
import requests
import json
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.options.android import UiAutomator2Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from urllib3.connection import port_by_scheme
# =======================
# 基础工具函数
# =======================
def run_command(command):
"""执行系统命令并返回输出"""
result = subprocess.run(command, shell=True, capture_output=True, text=True)
return result.stdout.strip()
# =======================
# API请求函数
# =======================
def get_new_port(yh_id):
"""从服务器获取新的端口号"""
url = "https://engineering.yuxindazhineng.com/index/index/get_yh_port"
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"yh_id": yh_id
}
try:
print(f"🔍 查询服务器新端口号用户ID: {yh_id}")
response = requests.post(url, headers=headers, data=data, timeout=10)
if response.status_code == 200:
result = response.json()
if result.get("code") == 0:
print(f"✅ 查询成功,新端口号: {result.get('data', '未知')}")
return result.get("data", None)
else:
print(f"❌ 查询失败: {result.get('msg', '未知错误')}")
return None
else:
print(f"❌ 服务器响应错误: {response.status_code}")
return None
except requests.exceptions.RequestException as e:
print(f"❌ 网络请求失败: {e}")
return None
def get_accounts_from_server(yh_id):
"""从服务器获取账户信息"""
url = "http://www.yuxindazhineng.com:3002/api/accounts/get_uplaod_data"
headers = {
"Content-Type": "application/json"
}
data = {
"yh_id": yh_id
}
try:
print(f"🔍 查询服务器账户信息用户ID: {yh_id}")
response = requests.post(url, headers=headers, json=data, timeout=10)
if response.status_code == 200:
result = response.json()
if result.get("code") == 0:
print(f"✅ 查询成功,找到 {result.get('total', 0)} 个账户")
return result.get("data", [])
else:
print(f"❌ 查询失败: {result.get('message', '未知错误')}")
return []
else:
print(f"❌ 服务器响应错误: {response.status_code}")
return []
except requests.exceptions.RequestException as e:
print(f"❌ 网络请求失败: {e}")
return []
except json.JSONDecodeError as e:
print(f"❌ JSON解析失败: {e}")
return []
def update_device_info(account_id, device_name, device_port, device_ip):
"""更新设备信息到服务器"""
url = "http://www.yuxindazhineng.com:3002/api/accounts/update"
headers = {
"Content-Type": "application/json"
}
data = {
"account_id": str(account_id),
"account_data": {
"device_name": str(device_name),
"device_port": str(device_port),
"device_ip": str(device_ip)
}
}
try:
print(f"🔄 更新设备信息账户ID: {account_id}")
print(f" 设备信息: 名称={device_name}, 端口={device_port}, IP={device_ip}")
response = requests.post(url, headers=headers, json=data, timeout=10)
if response.status_code == 200:
result = response.json()
if result.get("code") == 0:
print(f"✅ 更新成功: {result.get('message', '未知信息')}")
return True
else:
print(f"❌ 更新失败: {result.get('message', '未知错误')}")
return False
else:
print(f"❌ 服务器响应错误: {response.status_code}")
return False
except requests.exceptions.RequestException as e:
print(f"❌ 网络请求失败: {e}")
return False
# =======================
# Appium 启动
# =======================
def start_appium():
print("🚀 启动 Appium Server ...")
subprocess.Popen(
["appium.cmd", "-a", "127.0.0.1", "-p", "4723"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
time.sleep(5) # 给 Appium 启动时间
print("✅ Appium Server 已启动")
# =======================
# 启动沉降观测 App
# =======================
def start_settlement_app(device_id, device_ip, device_port):
print(f"📱 使用 Appium 连接设备: {device_id}")
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = device_id
options.udid = device_id
# ⚠️ TODO替换为你的真实信息
options.app_package = "com.bjjw.cjgc"
options.app_activity = ".activity.LoginActivity"
options.automation_name = "UiAutomator2"
options.no_reset = True
options.auto_grant_permissions = True
options.new_command_timeout = 28800
# 超时增强(无线 ADB 必须)
options.set_capability("uiautomator2ServerLaunchTimeout", 60000)
options.set_capability("adbExecTimeout", 120000)
driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=options
)
# 使用ADB命令启动Activity
try:
adb_command = f"adb -s {device_id} shell am start -n com.bjjw.cjgc/.activity.LoginActivity"
result = subprocess.run(adb_command, shell=True, capture_output=True, text=True)
if result.returncode == 0:
time.sleep(1) # 等待Activity启动
except Exception:
return False
print("✅ 沉降观测 App 已成功启动")
# =======================
# 获取用户名文本框内容
# =======================
app_username = None
try:
print("🔍 尝试获取用户名文本框内容...")
# 创建显式等待对象
wait = WebDriverWait(driver, 15) # 最多等待15秒
# 等待用户名文本框可点击
username_field = wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/et_user_name"))
)
# 获取文本框中的文本内容
app_username = username_field.text
# 如果文本框是空的尝试使用get_attribute获取文本
if not app_username:
app_username = username_field.get_attribute("text")
# 如果还是空的,尝试获取其他属性
if not app_username:
app_username = username_field.get_attribute("content-desc") or username_field.get_attribute("label")
if app_username:
print(f"✅ 成功获取到用户名: {app_username}")
else:
print("⚠️ 用户名文本框为空")
except Exception as e:
print(f"❌ 获取用户名失败: {e}")
return driver, app_username
# =======================
# 无线 ADB 建链主流程
# =======================
def setup_adb_wireless(yh_id="68c0dbfdb7cbcd616e7c5ab5"):
port = get_new_port(yh_id)
# port = 3435
print(f"🚀 开始无线 ADB 建链(端口 {port}")
print(f"📋 用户ID: {yh_id}")
# 从服务器获取账户信息
accounts = get_accounts_from_server(yh_id)
if not accounts:
print("❌ 未从服务器获取到账户信息,终止流程")
return
devices_output = run_command("adb devices")
lines = devices_output.splitlines()[1:]
usb_devices = []
for line in lines:
if not line.strip():
continue
device_id = line.split()[0]
# 跳过已经是无线的
if ":" in device_id:
continue
usb_devices.append(device_id)
if not usb_devices:
print("❌ 未检测到 USB 设备")
return
for serial in usb_devices:
print(f"\n🔎 处理设备: {serial}")
# 获取 WLAN IP
ip_info = run_command(f"adb -s {serial} shell ip addr show wlan0")
ip_match = re.search(r'inet\s+(\d+\.\d+\.\d+\.\d+)', ip_info)
if not ip_match:
print("⚠️ 获取 IP 失败,请确认已连接 WiFi")
continue
device_ip = ip_match.group(1)
print(f"📍 设备 IP: {device_ip}")
# 切 TCP 模式
run_command(f"adb -s {serial} tcpip {port}")
time.sleep(2)
# 无线连接
connect_result = run_command(f"adb connect {device_ip}:{port}")
if "connected" not in connect_result.lower():
print(f"❌ 无线连接失败: {connect_result}")
continue
wireless_id = f"{device_ip}:{port}"
print(f"✅ 无线 ADB 成功: {wireless_id}")
# ===== 后续自动化 =====
start_appium()
driver, app_username = start_settlement_app(wireless_id, device_ip, port)
if not app_username:
print("⚠️ 未获取到App中的用户名跳过服务器更新")
continue
# 在账户列表中查找匹配的用户名
matched_account = None
for account in accounts:
if account.get("username") == app_username:
matched_account = account
break
if not matched_account:
print(f"❌ 未找到与用户名 '{app_username}' 匹配的账户")
continue
print(f"✅ 找到匹配账户: {matched_account.get('cl_name')} ({matched_account.get('username')})")
print(f" account_id: {matched_account.get('account_id')}")
# 更新设备信息到服务器
device_name = serial # 使用设备序列号作为设备名称
# 构建更新数据
update_data = {
"account_id": matched_account.get("account_id"),
"device_name": device_name,
"device_port": port,
"device_ip": device_ip
}
success = update_device_info(
account_id=matched_account.get("account_id"),
device_name=device_name,
device_port=port,
device_ip=device_ip
)
if success:
print(f"🎉 所有操作完成! 账户 {matched_account.get('username')} 的设备信息已更新")
else:
print(f"⚠️ 设备信息更新失败但无线连接和App启动已完成")
# 关闭Appium连接
if driver:
print("🔄 关闭Appium连接...")
driver.quit()
break # 处理完第一个设备后退出,如需处理多个设备可移除此行
# =======================
# 程序入口
# =======================
if __name__ == "__main__":
# 配置参数
USER_ID = "68c0dbfdb7cbcd616e7c5ab5" # 替换为实际的用户ID
setup_adb_wireless(USER_ID)

Binary file not shown.

BIN
dist/沉降观测自动截图.exe vendored Normal file

Binary file not shown.

BIN
dist/自动导轨迹.exe vendored Normal file

Binary file not shown.

1112
get_line_code.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,385 @@
from turtle import done
import requests
import json
import logging
import socket
from typing import Optional, Dict, Any
import globals.global_variable as global_variable
import os
from datetime import datetime
import re
import threading
def fetch_and_save_track_file(url, base_save_dir="D:\\uploadInfo\\Logs"):
"""
获取追踪文件并保存到指定目录结构base_save_dir\\年月日\\文件名
:param url: 文件的完整URL地址
:param base_save_dir: 基础保存目录,默认为 D:\\uploadInfo\\Logs
:return: 成功返回保存的完整文件路径失败返回None
"""
try:
# 从URL中提取文件名
filename = os.path.basename(url)
# 获取当前日期格式YYYYMMDD
current_date = datetime.now().strftime("%Y%m")
# 构建完整的保存路径
save_dir = os.path.join(base_save_dir, current_date)
save_path = os.path.join(save_dir, filename)
print(f"正在从 {url} 获取文件...")
print(f"文件将保存到: {save_path}")
# 发送GET请求获取文件
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
# 尝试用UTF-8解码内容根据之前看到的内容应该是UTF-8
try:
content = response.content.decode('utf-8')
except UnicodeDecodeError:
# 如果UTF-8失败尝试其他常见编码
for encoding in ['gbk', 'gb2312', 'utf-8-sig']:
try:
content = response.content.decode(encoding)
print(f"使用 {encoding} 编码成功解码")
break
except UnicodeDecodeError:
continue
else:
print("无法解码文件内容,所有尝试的编码都失败")
return None
# 创建目录(如果不存在)
os.makedirs(save_dir, exist_ok=True)
# 保存文件到指定路径
with open(save_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"✅ 文件已成功保存到: {save_path}")
print(f"文件大小: {len(content)} 字符")
return save_path
except requests.exceptions.RequestException as e:
print(f"❌ 网络请求失败: {e}")
return None
except Exception as e:
print(f"❌ 处理文件时发生错误: {e}")
return None
def parse_track_file(file_path):
"""
解析本地追踪文件内容
:param file_path: 本地文件路径
:return: 解析后的记录列表
"""
records = []
try:
# 读取文件内容
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
lines = content.strip().split('\n')
for line in lines:
if not line.strip():
continue
# 按逗号分割
parts = line.split(',', 3)
if len(parts) >= 4:
try:
timestamp = parts[0].strip()
level = parts[1].strip()
account_info = parts[2].strip()
message = parts[3].strip()
# 从消息中提取线路ID和结束时间
line_id_match = re.search(r'([A-Z]\d+)', message)
end_time_match = re.search(r'结束时间:([\d-]+\s[\d:.]+)', message)
record = {
'timestamp': timestamp,
'level': level,
'account': account_info.replace('账号信息:', '').strip() if '账号信息:' in account_info else account_info,
'message': message
}
if line_id_match:
record['line_id'] = line_id_match.group(1)
if end_time_match:
record['end_time'] = end_time_match.group(1)
records.append(record)
except Exception as e:
print(f"解析行失败: {line[:50]}... 错误: {e}")
continue
print(f"✅ 成功解析 {len(records)} 条记录")
return records
except FileNotFoundError:
print(f"❌ 文件不存在: {file_path}")
return []
except Exception as e:
print(f"❌ 解析文件时发生错误: {e}")
return []
def deduplicate_by_line_id(records):
"""
按线路ID去重重复的线路ID保留后面出现的记录新写入的时间
:param records: 原始解析记录列表
:return: 去重后的记录字典key=line_id, value=record
"""
deduplicated_records = {}
for record in records:
# 只处理有线路ID的记录
if 'line_id' not in record or not record['line_id']:
continue
line_id = record['line_id']
# 后续出现的同线路ID记录会覆盖之前的实现"取后面新写入的时间"
deduplicated_records[line_id] = record
print(f"✅ 按线路ID去重后剩余 {len(deduplicated_records)} 条记录")
# 转换为列表返回字典values是去重后的记录
return list(deduplicated_records.values())
def get_latest_end_time(records, time_format="%Y-%m-%d %H:%M:%S.%f"):
"""
从解析后的记录中筛选出最晚的结束时间
:param records: 解析后的记录列表
:param time_format: 时间格式化字符串
:return: 最晚的结束时间字符串(原始格式)
"""
end_times = []
for record in records:
# 过滤无结束时间的记录
if 'end_time' not in record or not record['end_time']:
continue
try:
# 转换为datetime对象用于对比
time_obj = datetime.strptime(record['end_time'], time_format)
end_times.append((time_obj, record['end_time']))
except ValueError as e:
print(f"时间格式解析失败: {record['end_time']}, 错误: {e}")
continue
if not end_times:
print("❌ 未找到有效结束时间")
return None
# 按datetime对象排序取最后一个最晚的原始时间字符串
end_times.sort(key=lambda x: x[0])
latest_time = end_times[-1][1]
# 核心修改:截取到小数点前(去掉毫秒)
latest_time = latest_time.split('.')[0] # 按小数点分割,取第一部分
print(f"✅ 找到最晚结束时间: {latest_time}")
return latest_time
def write_to_file(content, file_path=r"D:\uploadInfo\end.txt", encoding='utf-8'):
"""
将内容写入指定文件
:param content: 要写入的内容
:param file_path: 目标文件路径
:param encoding: 文件编码
:return: 写入是否成功
"""
if content is None:
print("❌ 无有效内容可写入")
return False
try:
# 确保目录存在
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, 'w', encoding=encoding) as f:
f.write(content)
print(f"✅ 最晚结束时间已成功写入 {file_path}")
return True
except Exception as e:
print(f"❌ 写入文件失败: {e}")
return False
# def writer_file_status(username, last_time, to_status):
# """
# 安全地向 time.txt 中写入指定格式的新行
# 格式: 用户名 时间戳(YYYY-MM-DD HH:MM:SS) 状态
# 例如: CZSCZQ13A1xuliguo 2026-02-10 13:30:00 done
# :param username: 用户名如CZSCZQ13A1xuliguo
# :param from_status: 原状态(保留参数,兼容旧调用)
# :param to_status: 目标状态如done/running
# :return: 写入是否成功
# """
# # 确保文件存在(不存在则创建空文件)
# ## --- 配置区 ---
# API_URL = "http://your-api-server.com/api/tasks"
# MAX_WORKERS = 3
# TIME_FILE_PATH = r"D:\uploadInfo\time.txt"
# POLLING_INTERVAL = 600 # 10分钟轮询一次
# # 文件操作锁,防止多线程同时写入文件造成冲突
# file_lock = threading.Lock()
# if not os.path.exists(TIME_FILE_PATH):
# try:
# with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
# pass
# print(f"📄 文件 {TIME_FILE_PATH} 不存在,已创建")
# except Exception as e:
# print(f"❌ 创建文件失败: {e}")
# return False
# success = False
# with file_lock: # 加锁防止多线程写入冲突
# try:
# # 1. 获取当前时间,格式化为 YYYY-MM-DD HH:MM:SS
# # last_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# # 2. 构造指定格式的新行(核心修改处)
# new_line = f"{username} {last_time} {to_status}\n"
# # 3. 以追加模式写入文件
# with open(TIME_FILE_PATH, 'a', encoding='utf-8') as f:
# f.write(new_line)
# success = True
# print(f"📝 [文件更新] 已写入新行: {new_line.strip()}")
# return success
# except Exception as e:
# print(f"❌ 写入新行失败 ({username}): {e}")
# return False
def writer_file_status(username, last_time, to_status):
"""
安全地向 time.txt 中写入/更新指定格式的行
格式: 用户名 时间戳(YYYY-MM-DD HH:MM:SS) 状态
例如: CZSCZQ13A1xuliguo 2026-02-10 13:30:00 done
:param username: 用户名如CZSCZQ13A1xuliguo
:param last_time: 时间戳
:param to_status: 目标状态如done/running
:return: 写入是否成功
"""
# 确保文件存在(不存在则创建空文件)
TIME_FILE_PATH = r"D:\uploadInfo\time.txt"
# 文件操作锁,防止多线程同时写入文件造成冲突
file_lock = threading.Lock()
if not os.path.exists(TIME_FILE_PATH):
try:
with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
pass
print(f"📄 文件 {TIME_FILE_PATH} 不存在,已创建")
except Exception as e:
print(f"❌ 创建文件失败: {e}")
return False
success = False
with file_lock: # 加锁防止多线程写入冲突
try:
# 读取文件所有行
lines = []
username_found = False
# 如果文件不为空,读取现有内容
if os.path.getsize(TIME_FILE_PATH) > 0:
with open(TIME_FILE_PATH, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 处理每一行,查找并更新匹配的用户名
for i, line in enumerate(lines):
parts = line.strip().split()
if len(parts) >= 3 and parts[0] == username:
# 找到匹配的用户名且时间不一致,更新该行
# lines[i] = f"{username} {last_time} {to_status}\n"
username_found = True
existing_time = f"{parts[1]} {parts[2]}" # 组合日期和时间
existing_status = parts[3] if len(parts) > 3 else ""
# print(f"🔄 [文件更新] 已更新用户 {username} 的状态和时间为: {last_time} {to_status}")
# 检查时间和状态是否都一致
if existing_time == last_time and (existing_status == "done" or existing_status == "running" or existing_status == "ok"):
# 完全一致,不需要更新
print(f"⏭️ [文件更新跳过] 用户 {username} 的时间和状态与已有记录一致")
need_update = False
else:
# 时间或状态不一致,需要更新
lines[i] = f"{username} {last_time} {to_status}\n"
need_update = True
print(f"🔄 [文件更新] 已更新用户 {username} 的状态和时间为: {last_time} {to_status}")
break
# 如果没找到用户名,添加新行
if not username_found:
new_line = f"{username} {last_time} {to_status}\n"
lines.append(new_line)
print(f"📝 [文件更新] 已添加新用户行: {new_line.strip()}")
# 将更新后的内容写回文件
with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
f.writelines(lines)
success = True
return success
except Exception as e:
print(f"❌ 写入/更新失败 ({username}): {e}")
return False
def display_file_info(file_path, records=None):
"""
显示文件信息和内容预览
:param file_path: 文件路径
:param records: 解析后的记录(可选)
"""
if not os.path.exists(file_path):
print(f"❌ 文件不存在: {file_path}")
return
# 获取文件信息
file_size = os.path.getsize(file_path)
file_mod_time = datetime.fromtimestamp(os.path.getmtime(file_path))
print("\n" + "="*60)
print("📁 文件信息")
print("="*60)
print(f"文件路径: {file_path}")
print(f"文件大小: {file_size} 字节")
print(f"修改时间: {file_mod_time.strftime('%Y-%m-%d %H:%M:%S')}")
# 显示文件内容预览
print("\n" + "="*60)
print("📄 文件内容预览前5行")
print("="*60)
try:
with open(file_path, 'r', encoding='utf-8') as f:
lines = []
for i, line in enumerate(f):
if i < 5: # 只读取前5行
lines.append(line.strip())
else:
break
for i, line in enumerate(lines, 1):
print(f"{i:2d}. {line[:100]}{'...' if len(line) > 100 else ''}")
except Exception as e:
print(f"读取文件预览失败: {e}")
# 显示解析结果
if records:
print("\n" + "="*60)
print("📊 解析结果统计")
print("="*60)
print(f"总记录数: {len(records)}")
if records:
print("\n第一条记录详情:")
for key, value in records[0].items():
print(f" {key}: {value}")
def send_tcp_command(command="StartMultiple", host="127.0.0.1", port=8888, timeout=10):
"""
@@ -378,6 +754,107 @@ def get_user_max_variation(username: str) -> Optional[int]:
return None
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
# def get_line_info_and_save_global(user_name: str) -> bool:
# """
# 调用get_name_all接口提取status=3的line_num和line_name存入全局字典
# :param user_name: 接口请求参数,如"wangshun"
# :return: 执行成功返回True失败/异常返回False
# """
# # 接口基础配置
# api_url = "https://engineering.yuxindazhineng.com/index/index/get_name_all"
# request_params = {"user_name": user_name} # GET请求参数
# timeout = 10 # 请求超时时间(秒),避免卡进程
# try:
# # 1. 发送GET请求
# response = requests.get(
# url=api_url,
# params=request_params, # GET参数用params传递自动拼接到URL后规范且防乱码
# timeout=timeout,
# verify=False # 禁用SSL验证适配HTTPS接口
# )
# # 2. 校验HTTP状态码先确保请求本身成功
# if response.status_code != 200:
# logging.error(f"接口请求失败HTTP状态码异常{response.status_code},响应内容:{response.text}")
# return False
# # 3. 解析JSON响应接口返回是JSON格式需解析为字典
# try:
# response_data = response.json()
# except Exception as e:
# logging.error(f"接口返回内容非合法JSON无法解析{response.text},错误:{str(e)}")
# return False
# # 4. 校验业务状态码接口约定code=0成功-1失败
# business_code = response_data.get("code")
# if business_code == 0:
# logging.info("接口业务请求成功,开始解析数据")
# elif business_code == -1:
# logging.error(f"接口业务请求失败业务状态码code=-1返回数据{response_data}")
# return False
# else:
# logging.warning(f"接口返回未知业务状态码:{business_code},请确认接口文档")
# return False
# # 5. 提取data字段校验数据是否存在
# api_data_list = response_data.get("data")
# if not api_data_list:
# logging.warning("接口业务成功但data字段为空或无数据")
# return False
# # 6. 校验data是否为列表类型
# if not isinstance(api_data_list, list):
# logging.error(f"data字段不是列表类型实际类型{type(api_data_list)},内容:{api_data_list}")
# return False
# found_valid_data = False
# # 7. 遍历列表提取所有status=3的数据
# for item in api_data_list:
# # 确保每个item是字典
# if not isinstance(item, dict):
# logging.warning(f"列表中的元素不是字典类型,跳过:{item}")
# continue
# # 获取字段值
# data_status = item.get("status")
# line_num = item.get("line_num")
# line_name = item.get("line_name")
# # 校验status是否为3且目标字段非空
# if data_status == 3 and line_num and line_name:
# # # 存入全局字典key=line_numvalue=line_name
# # global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT[line_num] = line_name
# # 存入全局字典key=line_namevalue=line_num
# global_variable.get_upload_breakpoint_dict()[line_name] = line_num
# print(f"当前全局字典数据上传线路字典数据:{global_variable.get_upload_breakpoint_dict()}")
# # 如果line_name不在列表中则添加
# if line_name not in global_variable.get_upload_breakpoint_list():
# global_variable.get_upload_breakpoint_list().append(line_name)
# logging.info(f"找到status=3的线路信息line_num={line_num}, line_name={line_name}")
# found_valid_data = True
# if found_valid_data:
# logging.info(f"成功提取所有status=3的线路信息当前全局字典数据{global_variable.get_upload_breakpoint_dict()}")
# return True
# else:
# logging.warning("data列表中未找到任何status=3且字段完整的线路信息")
# return False
# # 捕获所有请求相关异常(超时、连接失败、网络异常等)
# except requests.exceptions.Timeout:
# logging.error(f"调用get_name_all接口超时超时时间{timeout}秒,请求参数:{request_params}")
# return False
# except requests.exceptions.ConnectionError:
# logging.error(f"调用get_name_all接口连接失败检查网络或接口地址是否正确{api_url}")
# return False
# except Exception as e:
# logging.error(f"调用get_name_all接口时发生未知异常{str(e)}", exc_info=True) # exc_info=True打印异常堆栈方便排查
# return False
def get_line_info_and_save_global(user_name: str) -> bool:
"""
调用get_name_all接口提取status=3的line_num和line_name存入全局字典
@@ -388,96 +865,139 @@ def get_line_info_and_save_global(user_name: str) -> bool:
api_url = "https://engineering.yuxindazhineng.com/index/index/get_name_all"
request_params = {"user_name": user_name} # GET请求参数
timeout = 10 # 请求超时时间(秒),避免卡进程
max_retries = 3 # 最大重试次数
retry_interval = 2 # 重试间隔(秒)
try:
# 1. 发送GET请求
response = requests.get(
url=api_url,
params=request_params, # GET参数用params传递自动拼接到URL后规范且防乱码
timeout=timeout,
verify=False # 禁用SSL验证适配HTTPS接口
)
# 2. 校验HTTP状态码先确保请求本身成功
if response.status_code != 200:
logging.error(f"接口请求失败HTTP状态码异常{response.status_code},响应内容:{response.text}")
return False
# 3. 解析JSON响应接口返回是JSON格式需解析为字典
for retry in range(max_retries):
try:
response_data = response.json()
except Exception as e:
logging.error(f"接口返回内容非合法JSON无法解析{response.text},错误:{str(e)}")
return False
# 1. 发送GET请求
response = requests.get(
url=api_url,
params=request_params, # GET参数用params传递自动拼接到URL后规范且防乱码
timeout=timeout,
verify=False # 禁用SSL验证适配HTTPS接口
)
# 4. 校验业务状态码接口约定code=0成功-1失败
business_code = response_data.get("code")
if business_code == 0:
logging.info("接口业务请求成功,开始解析数据")
elif business_code == -1:
logging.error(f"接口业务请求失败业务状态码code=-1返回数据{response_data}")
return False
else:
logging.warning(f"接口返回未知业务状态码:{business_code},请确认接口文档")
return False
# 2. 校验HTTP状态码先确保请求本身成功
if response.status_code != 200:
logging.error(f"接口请求失败HTTP状态码异常{response.status_code},响应内容:{response.text}")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
# 5. 提取data字段校验数据是否存在
api_data_list = response_data.get("data")
if not api_data_list:
logging.warning("接口业务成功但data字段为空或无数据")
return False
# 3. 解析JSON响应接口返回是JSON格式需解析为字典
try:
response_data = response.json()
except Exception as e:
logging.error(f"接口返回内容非合法JSON无法解析{response.text},错误:{str(e)}")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
# 6. 校验data是否为列表类型
if not isinstance(api_data_list, list):
logging.error(f"data字段不是列表类型实际类型{type(api_data_list)},内容:{api_data_list}")
return False
# 4. 校验业务状态码接口约定code=0成功-1失败
business_code = response_data.get("code")
if business_code == 0:
logging.info("接口业务请求成功,开始解析数据")
elif business_code == -1:
logging.error(f"接口业务请求失败业务状态码code=-1返回数据{response_data}")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
else:
logging.warning(f"接口返回未知业务状态码:{business_code},请确认接口文档")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
found_valid_data = False
# 5. 提取data字段校验数据是否存在
api_data_list = response_data.get("data")
if not api_data_list:
logging.warning("接口业务成功但data字段为空或无数据")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
# 7. 遍历列表提取所有status=3的数据
for item in api_data_list:
# 确保每个item是字典
if not isinstance(item, dict):
logging.warning(f"列表中的元素不是字典类型,跳过:{item}")
# 6. 校验data是否为列表类型
if not isinstance(api_data_list, list):
logging.error(f"data字段不是列表类型实际类型{type(api_data_list)},内容:{api_data_list}")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
found_valid_data = False
# 7. 遍历列表提取所有status=3的数据
for item in api_data_list:
# 确保每个item是字典
if not isinstance(item, dict):
logging.warning(f"列表中的元素不是字典类型,跳过:{item}")
continue
# 获取字段值
data_status = item.get("status")
line_num = item.get("line_num")
line_name = item.get("line_name")
# 校验status是否为3且目标字段非空
if data_status == 3 and line_num and line_name:
# # 存入全局字典key=line_numvalue=line_name
# global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT[line_num] = line_name
# 存入全局字典key=line_namevalue=line_num
global_variable.get_upload_breakpoint_dict()[line_name] = line_num
print(f"当前全局字典数据上传线路字典数据:{global_variable.get_upload_breakpoint_dict()}")
# 如果line_name不在列表中则添加
if line_name not in global_variable.get_upload_breakpoint_list():
global_variable.get_upload_breakpoint_list().append(line_name)
logging.info(f"找到status=3的线路信息line_num={line_num}, line_name={line_name}")
found_valid_data = True
if found_valid_data:
logging.info(f"成功提取所有status=3的线路信息当前全局字典数据{global_variable.get_upload_breakpoint_dict()}")
return True
else:
logging.warning("data列表中未找到任何status=3且字段完整的线路信息")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
# 捕获所有请求相关异常(超时、连接失败、网络异常等)
except requests.exceptions.Timeout:
logging.error(f"调用get_name_all接口超时超时时间{timeout}秒,请求参数:{request_params}")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
except requests.exceptions.ConnectionError:
logging.error(f"调用get_name_all接口连接失败检查网络或接口地址是否正确{api_url}")
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
return False
except Exception as e:
logging.error(f"调用get_name_all接口时发生未知异常{str(e)}", exc_info=True) # exc_info=True打印异常堆栈方便排查
if retry < max_retries - 1:
logging.info(f"将在{retry_interval}秒后进行第{retry+2}次重试")
time.sleep(retry_interval)
continue
# 获取字段值
data_status = item.get("status")
line_num = item.get("line_num")
line_name = item.get("line_name")
# 校验status是否为3且目标字段非空
if data_status == 3 and line_num and line_name:
# # 存入全局字典key=line_numvalue=line_name
# global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT[line_num] = line_name
# 存入全局字典key=line_namevalue=line_num
global_variable.get_upload_breakpoint_dict()[line_name] = line_num
print(f"当前全局字典数据上传线路字典数据:{global_variable.get_upload_breakpoint_dict()}")
# 如果line_name不在列表中则添加
if line_name not in global_variable.get_upload_breakpoint_list():
global_variable.get_upload_breakpoint_list().append(line_name)
logging.info(f"找到status=3的线路信息line_num={line_num}, line_name={line_name}")
found_valid_data = True
if found_valid_data:
logging.info(f"成功提取所有status=3的线路信息当前全局字典数据{global_variable.get_upload_breakpoint_dict()}")
return True
else:
logging.warning("data列表中未找到任何status=3且字段完整的线路信息")
return False
# 捕获所有请求相关异常(超时、连接失败、网络异常等)
except requests.exceptions.Timeout:
logging.error(f"调用get_name_all接口超时超时时间{timeout}秒,请求参数:{request_params}")
return False
except requests.exceptions.ConnectionError:
logging.error(f"调用get_name_all接口连接失败检查网络或接口地址是否正确{api_url}")
return False
except Exception as e:
logging.error(f"调用get_name_all接口时发生未知异常{str(e)}", exc_info=True) # exc_info=True打印异常堆栈方便排查
return False
def get_accounts_from_server(yh_id):
"""从服务器获取账户信息"""

View File

@@ -629,7 +629,7 @@ def launch_app_manually(driver, device_id, package_name="com.bjjw.cjgc", activit
# 使用ADB命令设置屏幕永不休眠
screen_timeout_cmd = [
"adb", "-s", device_id,
"shell", "settings", "put", "system", "screen_off_timeout", "0"
"shell", "settings", "put", "system", "screen_off_timeout", "86400000"
]
timeout_result = subprocess.run(screen_timeout_cmd, capture_output=True, text=True, timeout=15)
if timeout_result.returncode == 0:

View File

@@ -126,6 +126,8 @@ def set_upload_success_breakpoint_list(success_list):
"""设置上传成功的断点列表"""
thread_local.GLOBAL_UPLOAD_SUCCESS_BREAKPOINT_LIST = success_list
# 为了保持 ,保留原有的全局变量名称
# 但这些将不再被直接使用,而是通过上面的函数访问
GLOBAL_DEVICE_ID = "" # 设备ID

View File

@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
## --- 配置区 ---
API_URL = "http://your-api-server.com/api/tasks" # 替换为真实的接口地址
MAX_WORKERS = 3 # 最大并发线程数,建议根据网络带宽调整
TIME_FILE_PATH = r"D:\time.txt" # 电脑D盘下的路径
TIME_FILE_PATH = r"D:\uploadInfo\time.txt" # 电脑D盘下的路径
def parse_time_config():
"""
@@ -53,7 +53,7 @@ def get_remote_tasks():
return {}
# 2. 从服务器获取账户
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
accounts = apis.get_accounts_from_server("68ef0e02b0138d25e2ac9918")
if not accounts:
print("❌ 未从服务器获取到账户信息,终止流程")
return {}

20
main.py
View File

@@ -16,9 +16,7 @@ import permissions # 导入权限处理模块
import globals.apis as apis
from globals.driver_utils import init_appium_driver, ensure_appium_server_running, safe_quit_driver, is_app_launched, launch_app_manually
from page_objects.login_page import LoginPage
from page_objects.download_tabbar_page import DownloadTabbarPage
from page_objects.screenshot_page import ScreenshotPage
from page_objects.upload_config_page import UploadConfigPage
from page_objects.more_download_page import MoreDownloadPage
@@ -35,8 +33,14 @@ logging.basicConfig(
class DeviceAutomation(object):
def __init__(self, device_id=None):
def __init__(self, device_id=None, project_name=None):
self.device_id = device_id
self.project_name = project_name
# 设置项目名称到全局变量
if project_name:
global_variable.set_current_project_name(project_name)
logging.info(f"设备 {self.device_id} 已设置项目名称: {project_name}")
# 初始化权限
if permissions.grant_appium_permissions(self.device_id):
@@ -62,9 +66,7 @@ class DeviceAutomation(object):
# 初始化页面对象
logging.info(f"设备 {self.device_id} 开始初始化页面对象")
self.login_page = LoginPage(self.driver, self.wait)
self.download_tabbar_page = DownloadTabbarPage(self.driver, self.wait, self.device_id)
self.screenshot_page = ScreenshotPage(self.driver, self.wait, self.device_id)
self.upload_config_page = UploadConfigPage(self.driver, self.wait, self.device_id)
self.more_download_page = MoreDownloadPage(self.driver, self.wait,self.device_id)
logging.info(f"设备 {self.device_id} 所有页面对象初始化完成")
@@ -142,7 +144,7 @@ class DeviceAutomation(object):
measure_page_btn.click()
# 处理平差
# 处理截图
self.screenshot_page.screenshot_page_manager(self.device_id)
return True
@@ -246,13 +248,15 @@ class DeviceAutomation(object):
safe_quit_driver(getattr(self, 'driver', None), self.device_id)
@staticmethod
def start_upload(device_id=None, upload_time=None):
def start_upload(device_id=None, upload_time=None, project_name=None):
"""
供其他页面或模块调用的静态方法
执行完整的自动化流程
参数:
device_id: 可选的设备ID如果为None则自动获取
upload_time: 上传时间
project_name: 项目名称
返回:
bool: 自动化流程执行结果True/False
@@ -260,7 +264,7 @@ class DeviceAutomation(object):
automation = None
try:
# 创建自动化实例
automation = DeviceAutomation(device_id=device_id)
automation = DeviceAutomation(device_id=device_id, project_name=project_name)
# 执行自动化流程
success = automation.run_automation()

View File

@@ -59,7 +59,7 @@ class LoginPage:
# 如果clear方法不可用尝试其他方式
pass
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
accounts = apis.get_accounts_from_server("68ef0e02b0138d25e2ac9918")
matches = [acc for acc in accounts if acc.get("username") == existing_username]
if matches:
password = matches[0].get("password")

View File

@@ -1,9 +1,11 @@
# screenshot_page.py
from socket import TCP_NODELAY
import subprocess
import logging
import time
import re
import os
import threading
from datetime import datetime
from appium.webdriver.common.appiumby import AppiumBy
from selenium.common.exceptions import NoSuchElementException, TimeoutException
@@ -19,7 +21,7 @@ import globals.global_variable as global_variable # 导入全局变量模块
class ScreenshotPage:
def __init__(self, driver, wait, device_id=None):
self.driver = driver
self.wait = wait
self.wait = WebDriverWait(driver, 2)
self.device_id = device_id
self.logger = logging.getLogger(__name__)
self.all_items = set()
@@ -528,7 +530,7 @@ class ScreenshotPage:
self.logger.error(f"设备 {device_id} 检查WiFi状态时发生错误: {str(e)}")
return None
def take_screenshot(self, filename_prefix="screenshot"):
def take_screenshot(self, filename_prefix="screenshot", date_str=None, time_str=None):
"""
通过Appium驱动截取设备屏幕
@@ -539,20 +541,59 @@ class ScreenshotPage:
bool: 操作是否成功
"""
try:
# 创建测试结果目录
screenshots_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../test_results/screenshots')
if not os.path.exists(screenshots_dir):
os.makedirs(screenshots_dir)
self.logger.info(f"创建截图目录: {screenshots_dir}")
# 获取项目名称
project_name = global_variable.get_current_project_name() or "默认项目"
# 获取当前日期
date_str = datetime.now().strftime("%Y%m%d")
# if not date_str:
# date_str = datetime.now().strftime("%Y%m%d")
# 获取当前时间(如果没有提供),并确保格式合法(不含冒号)
if not time_str:
time_str = datetime.now().strftime("%H%M%S")
else:
# 移除时间中的冒号,确保文件名合法
time_str = time_str.replace(":", "")
# 创建D盘下的截图目录结构D:\uploadInfo\picture\项目名\年月日
screenshots_dir = os.path.join("D:\\", "uploadInfo", "picture", project_name, date_str)
# 确保目录存在
try:
os.makedirs(screenshots_dir, exist_ok=True)
self.logger.info(f"截图目录: {screenshots_dir}")
except Exception as dir_error:
self.logger.error(f"创建截图目录失败: {str(dir_error)}")
return False
line_code = global_variable.get_upload_breakpoint_dict().get(filename_prefix)
if not line_code:
self.logger.error(f"未找到与断点名称 {filename_prefix} 对应的线路编码")
line_code = "unknown"
# 截图保存
screenshot_file = os.path.join(
screenshots_dir,
f"{filename_prefix}_{datetime.now().strftime('%Y%m%d')}.png"
f"{line_code}_{filename_prefix}_{time_str}.png"
)
self.driver.save_screenshot(screenshot_file)
self.logger.info(f"截图已保存: {screenshot_file}")
return True
# 尝试保存截图
try:
success = self.driver.save_screenshot(screenshot_file)
if success:
self.logger.info(f"截图已保存: {screenshot_file}")
# 验证文件是否真的存在
if os.path.exists(screenshot_file):
self.logger.info(f"截图文件验证存在: {screenshot_file}")
else:
self.logger.warning(f"截图文件保存成功但验证不存在: {screenshot_file}")
return True
else:
self.logger.error(f"Appium截图保存失败: {screenshot_file}")
return False
except Exception as save_error:
self.logger.error(f"保存截图时发生错误: {str(save_error)}")
return False
except Exception as e:
self.logger.error(f"截图时发生错误: {str(e)}")
@@ -571,14 +612,28 @@ class ScreenshotPage:
"""
try:
# D盘txt文件路径
txt_file_path = "D:\\uploadInfo\\screenshot_status.txt"
# txt_file_path = "D:\\uploadInfo\\screenshot_status.txt"
date_str = datetime.now().strftime("%Y%m%d")
project_name = global_variable.get_current_project_name() or "默认项目"
# 创建D盘下的截图目录结构D:\uploadInfo\picture\项目名\年月日
screenshots_dir = os.path.join("D:\\", "uploadInfo", "picture", project_name, date_str)
# 确保目录存在
try:
os.makedirs(screenshots_dir, exist_ok=True)
self.logger.info(f"截图数据保存目录: {screenshots_dir}")
txt_file_path = os.path.join(screenshots_dir, "screenshot_status.txt")
except Exception as dir_error:
self.logger.error(f"创建截图目录失败: {str(dir_error)}")
return False
# 获取当前时间
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 状态信息
status = "成功" if success else "失败"
status_line = f"{current_time} - {breakpoint_name} - 截图{status}\n"
logo = "" if success else ""
status_line = f"{logo}{current_time} - {breakpoint_name} - 截图{status}\n"
# 追加写入文件
with open(txt_file_path, 'a', encoding='utf-8') as f:
@@ -591,117 +646,79 @@ class ScreenshotPage:
self.logger.error(f"写入截图状态文件时发生错误: {str(e)}")
return False
def wait_for_measurement_end(self, timeout=900):
def update_file_status(self, username, from_status, to_status):
"""
等待按钮变成"测量结束"最多15分钟包含驱动重新初始化机制
Args:
timeout: 超时时间默认900秒15分钟
Returns:
bool: 是否成功等到测量结束按钮
安全地更新 time.txt 中该用户的状态
例如: 将 'true' 改为 'running', 或将 'running' 改为 'done'
"""
try:
# 更新WebDriverWait等待时间为900秒
self.wait = WebDriverWait(self.driver, 900)
self.logger.info(f"设备等待测量结束按钮出现,最多等待 {timeout}")
start_time = time.time()
reinit_attempts = 0
max_reinit_attempts = 3 # 最大重新初始化次数
while time.time() - start_time < timeout:
try:
# 使用XPath查找文本为"测量结束"的按钮
measurement_end_button = self.driver.find_element(
AppiumBy.XPATH,
"//android.widget.Button[@text='测量结束']"
)
if measurement_end_button.is_displayed() and measurement_end_button.is_enabled():
self.logger.info(f"设备检测到测量结束按钮")
return True
except NoSuchElementException:
# 按钮未找到,继续等待
pass
except Exception as e:
error_msg = str(e)
self.logger.warning(f"设备查找测量结束按钮时出现异常: {error_msg}")
# 检测是否是UiAutomator2服务崩溃
if 'UiAutomator2 server' in error_msg and 'instrumentation process is not running' in error_msg and reinit_attempts < max_reinit_attempts:
reinit_attempts += 1
self.logger.info(f"设备检测到UiAutomator2服务崩溃尝试第 {reinit_attempts} 次重新初始化驱动")
# 尝试重新初始化驱动
if self._reinit_driver():
self.logger.info(f"设备驱动重新初始化成功")
else:
self.logger.error(f"设备驱动重新初始化失败")
# 继续尝试,而不是立即失败
# 等待一段时间后再次检查
time.sleep(3)
# 每30秒输出一次等待状态
if int(time.time() - start_time) % 30 == 0:
elapsed = int(time.time() - start_time)
self.logger.info(f"设备 {self.device_id} 已等待 {elapsed} 秒,仍在等待测量结束...")
self.logger.error(f"设备 {self.device_id} 等待测量结束按钮超时")
TIME_FILE_PATH = r"D:\uploadInfo\time.txt"
if not os.path.exists(TIME_FILE_PATH):
return False
except Exception as e:
self.logger.error(f"设备 {self.device_id} 等待测量结束时发生错误: {str(e)}")
return False
success = False
file_lock = threading.Lock()
with file_lock:
try:
with open(TIME_FILE_PATH, 'r', encoding='utf-8') as f:
lines = f.readlines()
def _reinit_driver(self):
# new_lines = []
# for line in lines:
# clean_line = line.strip()
# # 匹配逻辑:包含用户名 且 以 from_status 结尾
# if f" {username} " in line and clean_line.endswith(from_status):
# line = line.replace(from_status, to_status)
# success = True
# new_lines.append(line)
new_lines = []
for line in lines:
# 使用正则确保精准匹配用户名和结尾状态
# 匹配规则:行内包含该用户名,且该行以 from_status 结尾
if re.search(rf'\b{username}\b', line) and line.strip().endswith(from_status):
# 只替换行尾的那个状态词
line = re.sub(rf'{from_status}$', to_status, line.rstrip()) + '\n'
success = True
new_lines.append(line)
with open(TIME_FILE_PATH, 'w', encoding='utf-8') as f:
f.writelines(new_lines)
if success:
print(f"📝 [文件更新] 用户 {username}: {from_status} -> {to_status}")
return success
except Exception as e:
print(f"❌ 更新文件状态失败 ({username}): {e}")
return False
def update_upload_info_status(self, status):
"""
重新初始化Appium驱动
更新D:/uploadInfo文件夹下的time.txt文件的状态
Returns:
bool: 是否成功重新初始化
参数:
status: 状态值,如"ok""again"
返回:
bool: 操作是否成功
"""
try:
# 首先尝试关闭现有的驱动
if hasattr(self, 'driver') and self.driver:
try:
self.driver.quit()
except:
self.logger.warning("关闭现有驱动时出现异常")
# time.txt文件路径
time_file_path = "D:\\uploadInfo\\time.txt"
# 导入必要的模块
from appium import webdriver
from appium.options.android import UiAutomator2Options
# 确保文件夹存在
os.makedirs(os.path.dirname(time_file_path), exist_ok=True)
# 重新创建驱动配置
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = self.device_id
options.app_package = "com.bjjw.cjgc"
options.app_activity = ".activity.LoginActivity"
options.automation_name = "UiAutomator2"
options.no_reset = True
options.auto_grant_permissions = True
options.new_command_timeout = 300
options.udid = self.device_id
# 写入状态
with open(time_file_path, 'w', encoding='utf-8') as f:
f.write(status)
# 重新连接驱动
self.logger.info(f"正在重新初始化设备 {self.device_id} 的驱动...")
self.driver = webdriver.Remote("http://localhost:4723", options=options)
# 重新初始化等待对象
from selenium.webdriver.support.ui import WebDriverWait
self.wait = WebDriverWait(self.driver, 1)
self.logger.info(f"设备 {self.device_id} 驱动重新初始化完成")
self.logger.info(f"已更新上传状态文件: {time_file_path} -> {status}")
return True
except Exception as e:
self.logger.error(f"设备 {self.device_id} 驱动重新初始化失败: {str(e)}")
self.logger.error(f"更新上传状态文件时发生错误: {str(e)}")
return False
def handle_confirmation_dialog(self, device_id, timeout=2):
"""
处理确认弹窗,点击""按钮
@@ -808,7 +825,7 @@ class ScreenshotPage:
if confirm_button and confirm_button.is_displayed() and confirm_button.is_enabled():
self.logger.info(f"设备 {device_id} 点击确认弹窗的''按钮")
confirm_button.click()
time.sleep(1)
time.sleep(0.5)
# 验证弹窗是否消失
try:
@@ -828,7 +845,7 @@ class ScreenshotPage:
except Exception as e:
self.logger.warning(f"设备 {device_id} 查找确认弹窗时出现异常: {str(e)}")
time.sleep(1)
time.sleep(0.5)
self.logger.error(f"设备 {device_id} 等待返回确认弹窗超时")
return False
@@ -1001,7 +1018,7 @@ class ScreenshotPage:
# 3. 验证是否成功返回到上一页面
time.sleep(1) # 等待页面跳转完成
time.sleep(0.5) # 等待页面跳转完成
# 可以添加页面验证逻辑,比如检查是否返回到预期的页面
# 这里可以根据实际应用添加特定的页面元素验证
@@ -1013,51 +1030,6 @@ class ScreenshotPage:
self.logger.error(f"设备 {device_id} 执行返回导航步骤时发生错误: {str(e)}")
return False
def scroll_to_bottom_and_screenshot(self, device_id):
"""
检测到测量结束后下滑列表到最底端点击最后一个spinner再下滑一次点击平差处理按钮后截图
Args:
device_id: 设备ID
Returns:
bool: 操作是否成功
"""
try:
self.logger.info(f"设备 {device_id} 开始执行测量结束后的操作流程")
time.sleep(5)
# 1. 下滑列表到最底端
if not self.scroll_list_to_bottom(device_id):
self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
return False
# 2. 点击最后一个spinner
if not self.click_last_spinner_with_retry(device_id):
self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
return False
# 3. 再下滑一次
if not self.scroll_down_once(device_id):
self.logger.warning(f"设备 {device_id} 再次下滑失败,但继续执行")
# 4. 点击平差处理按钮
if not self.click_adjustment_button(device_id):
self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
return False
# 5. 在点击平差处理按钮后截图
time.sleep(2) # 等待平差处理按钮点击后的界面变化
if not self.take_screenshot("after_adjustment_button_click"):
self.logger.error(f"设备 {device_id} 截图失败")
return False
self.logger.info(f"设备 {device_id} 测量结束后操作流程完成")
return True
except Exception as e:
self.logger.error(f"设备 {device_id} 执行测量结束后操作时发生错误: {str(e)}")
return False
def scroll_list_to_bottom(self, device_id, max_swipes=60):
"""
@@ -1075,16 +1047,22 @@ class ScreenshotPage:
# 获取列表元素
list_view = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/auto_data_list")
self.logger.info(f"时间戳1: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
same_content_count = 0
# 初始化第一次的子元素文本
initial_child_elements = list_view.find_elements(AppiumBy.CLASS_NAME, "android.widget.TextView")
current_child_texts = "|".join([
elem.text.strip() for elem in initial_child_elements
if elem.text and elem.text.strip()
])
self.logger.info(f"时间戳2: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
# current_child_texts = "|".join([
# elem.text.strip() for elem in initial_child_elements
# if elem.text and elem.text.strip()
# ])
current_child_texts = "|".join(
elem_text.strip() for elem in initial_child_elements
if (elem_text := elem.text) and elem_text.strip()
)
self.logger.info(f"时间戳3: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
for i in range(max_swipes):
# 执行下滑操作
self.driver.execute_script("mobile: scrollGesture", {
@@ -1094,14 +1072,12 @@ class ScreenshotPage:
'duration': 500
})
time.sleep(0.5)
# 获取滑动后的子元素文本
new_child_elements = list_view.find_elements(AppiumBy.CLASS_NAME, "android.widget.TextView")
new_child_texts = "|".join([
elem.text.strip() for elem in new_child_elements
if elem.text and elem.text.strip()
])
new_child_texts = "|".join(
elem_text.strip() for elem in new_child_elements
if (elem_text := elem.text) and elem_text.strip()
)
# 判断内容是否变化若连续3次相同认为到达底部
if new_child_texts == current_child_texts:
@@ -1129,7 +1105,7 @@ class ScreenshotPage:
if self.click_last_spinner(device_id):
return True
self.logger.warning(f"设备 {device_id}{attempt + 1}次点击失败,准备重试")
time.sleep(1) # 重试前等待
time.sleep(0.5) # 重试前等待
except Exception as e:
self.logger.error(f"设备 {device_id}{attempt + 1}次尝试失败: {str(e)}")
@@ -1280,7 +1256,7 @@ class ScreenshotPage:
'percent': 0.5
})
time.sleep(1)
time.sleep(0.2)
self.logger.info(f"设备 {device_id} 额外下滑完成")
return True
@@ -1380,7 +1356,7 @@ class ScreenshotPage:
self.logger.info(f"设备 {device_id} 等待 {timeout} 秒未发现确认弹窗,可能没有弹窗,返回成功")
return True
def load_line_time_mapping_dict(self, filename="20251022.1.CZSCZQ-3fhg0410.txt", log_directory="D:\\soft\\安卓时间修改-v0.7.13-1\\Logs\\202510", poll_interval=120, max_wait_time=18000):
def load_line_time_mapping_dict(self, filename="20251022.1.CZSCZQ-3fhg0410.txt", log_directory="D:\\uploadInfo\\Logs\\202510", poll_interval=120, max_wait_time=18000):
"""
加载指定文件中的线路编码和时间到全局字典
参数:
@@ -1398,7 +1374,7 @@ class ScreenshotPage:
# 获取当前年月日例如20251023
current_date = datetime.now().strftime("%Y%m%d")
# 拼接格式:年月日.1.用户名.txt
filename = f"{current_date}.1.{global_variable.get_username()}.txt"
filename = f"{current_date}_1_{global_variable.get_username()}.txt"
file_path = os.path.join(log_directory, filename)
# 轮询等待文件出现
@@ -1466,7 +1442,7 @@ class ScreenshotPage:
"""执行截图页面管理操作"""
try:
# 加载指定文件中的线路编码和时间到全局字典
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\soft\\安卓时间修改-v0.7.13-1\\Logs\\202510"):
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\uploadInfo\\Logs\\202510"):
self.logger.error(f"设备 {device_id} 加载线路时间映射字典失败")
return False
@@ -1496,7 +1472,7 @@ class ScreenshotPage:
time.sleep(60) # 等待3分钟
# 重新加载文件
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\soft\\安卓时间修改-v0.7.13-1\\Logs\\202510"):
if not self.load_line_time_mapping_dict("20251022.1.CZSCZQ-3fhg0410.txt", "D:\\uploadInfo\\Logs\\202510"):
self.logger.error(f"设备 {device_id} 重新加载线路时间映射字典失败")
else:
self.logger.info(f"设备 {device_id} 重新加载完成,新的线路时间数量: {len(global_variable.get_line_time_mapping_dict())}")
@@ -1510,7 +1486,7 @@ class ScreenshotPage:
# 检查GLOBAL_BREAKPOINT_DICT是否为空如果为空则初始化一些测试数据
if not global_variable.get_upload_breakpoint_dict():
self.logger.warning("global_variable.get_upload_breakpoint_dict()为空,正在初始化测试数据")
# 添加一些测试断点数据,实际使用时应该从其他地方加载
# 添加一些测试断点数据,实际使用时是接口返回
# 注意这里的值应该是字典与section_mileage_config_page.py中的数据结构保持一致
global_variable.set_breakpoint_dict({
"CZSCZQ-3-康定2号隧道-DK297+201-DK297+199-山区": {
@@ -1523,100 +1499,269 @@ class ScreenshotPage:
}
})
# 开始循环
for breakpoint_name in global_variable.get_upload_breakpoint_dict().keys():
self.logger.info(f"开始处理要平差截图的断点 {breakpoint_name}")
# 把断点名称给find_keyword
if not self.find_keyword(breakpoint_name):
self.logger.error(f"设备 {device_id} 未找到包含 {breakpoint_name} 的文件名")
return False
breakpoint_names = list(global_variable.get_upload_breakpoint_dict().keys())
self.logger.info(f"设备 {device_id} 获取的断点名称列表: {breakpoint_names}")
processed_breakpoints = [] # 创建一个列表,用于记录已处理的断点
# 开始循环处理断点
# 检测当前页面获取到的标段是否在breakpoint_names中
max_scroll_attempts = 100 # 最大滚动尝试次数
scroll_count = 0
previous_items = set() # 记录前一次获取的项目集合,用于检测是否到达边界
found_any = False # 标记是否找到并处理了任何断点
max_retry_attempts = 3 # 每个断点的最大重试次数
all_success = True
if not self.handle_measurement_dialog():
self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
return False
while scroll_count < max_scroll_attempts:
# 获取当前页面中的所有项目
current_items = self.get_current_items()
self.logger.info(f"当前页面找到 {len(current_items)} 个项目")
if not self.check_apply_btn():
self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
return False
# 检查当前页面的项目是否在breakpoint_names中
for item in current_items:
# 检查项目是否在breakpoint_names中且未处理
if item in breakpoint_names and item not in processed_breakpoints:
self.logger.info(f"找到目标断点: {item}")
found_any = True
line_code = None
# 获取线路编码
try:
line_code = global_variable.get_upload_breakpoint_dict()[item]
except KeyError:
self.logger.error(f"未找到断点 {item} 的线路编码")
continue
# 根据断点名称在get_upload_breakpoint_dict()中获取线路编码
line_code = global_variable.get_upload_breakpoint_dict().get(breakpoint_name)
if not line_code:
self.logger.error(f"设备 {device_id} 未找到断点 {breakpoint_name} 对应的线路编码")
return False
# 重试处理断点
retry_count = 0
while retry_count < max_retry_attempts:
self.logger.info(f"开始处理断点 {item} (第 {retry_count + 1} 次尝试)")
# 根据线路编码查找对应的时间
date_str, time_str = self.get_line_end_time(line_code)
if not time_str or not date_str:
self.logger.error(f"设备 {device_id} 未找到线路 {line_code} 对应的时间")
return False
# 点击目标项目
if not self.click_item_by_text(item):
self.logger.error(f"点击目标断点失败: {item}")
retry_count += 1
all_success = False
continue
# 修改时间
if not self.set_device_time(device_id, time_str, date_str):
self.logger.error(f"设备 {device_id} 设置设备时间失败")
return False
if not self.handle_measurement_dialog():
self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
retry_count += 1
all_success = False
continue
# 滑动列表到底部
if not self.scroll_list_to_bottom(device_id):
self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
return False
if not self.check_apply_btn():
self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
retry_count += 1
all_success = False
self.click_back_button(device_id)
continue
# 2. 点击最后一个spinner
if not self.click_last_spinner_with_retry(device_id):
self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
return False
# 根据线路编码查找对应的时间
date_str, time_str = self.get_line_end_time(line_code)
if not time_str or not date_str:
self.logger.error(f"设备 {device_id} 未找到线路 {line_code} 对应的时间")
retry_count += 1
all_success = False
continue
# 3. 再下滑一次
if not self.scroll_down_once(device_id):
self.logger.warning(f"设备 {device_id} 再次下滑失败,但继续执行")
# 修改时间
if not self.set_device_time(device_id, time_str, date_str):
self.logger.error(f"设备 {device_id} 设置设备时间失败")
retry_count += 1
all_success = False
continue
# # 4. 点击平差处理按钮
# if not self.click_adjustment_button(device_id):
# self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
# return False
# 滑动列表到底部
if not self.scroll_list_to_bottom(device_id):
self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
retry_count += 1
all_success = False
continue
# # 检查是否在测量页面在就重新执行选择断点滑动列表到底部点击最后一个spinner 再下滑一次,点击平差处理按钮平差
# if not self.handle_back_navigation(breakpoint_name, device_id):
# self.logger.error(f"{breakpoint_name}平差失败,未截图")
# return False
# 2. 点击最后一个spinner
if not self.click_last_spinner_with_retry(device_id):
self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
retry_count += 1
all_success = False
continue
# 3. 再下滑一次
while True:
if self.scroll_down_once(device_id):
self.logger.warning(f"设备 {device_id} 下滑成功,跳出下滑一次循环")
break
else:
self.logger.warning(f"设备 {device_id} 下滑失败,循环执行下滑一次")
# # 检测并处理"是 保留成果"弹窗
# if not self.handle_adjustment_result_dialog():
# self.logger.error("处理平差结果弹窗失败")
# return False
# 平差处理完成后截图
time.sleep(0.2) # 等待平差处理按钮点击后的界面变化
logging.info("断点保存到上传列表成功,开始截图")
# png_time = date_str + " " + time_str
if not self.take_screenshot(item, date_str, time_str):
self.logger.error(f"设备 {device_id} 截图失败")
self.write_screenshot_status(item, success=False)
retry_count += 1
all_success = False
else:
self.write_screenshot_status(item, success=True)
# # 平差完成,将断点数据保存到上传列表中
# if not self.add_breakpoint_to_upload_list(breakpoint_name, line_code):
# self.logger.error(f"设备 {device_id} 保存断点 {breakpoint_name} 到上传列表失败")
# return False
# 点击返回按钮并处理弹窗
if not self.execute_back_navigation_steps(device_id):
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
retry_count += 1
all_success = False
# # 禁用WiFi
# if not self.disable_wifi(device_id):
# self.logger.error(f"设备 {device_id} 禁用WiFi失败")
# return False
# 成功处理完一个断点,添加到已处理列表
processed_breakpoints.append(item)
if item in processed_breakpoints: # 跳过重复处理
self.logger.info(f"成功处理断点: {item}")
break # 跳出重试循环
# 平差处理完成后截图
time.sleep(3) # 等待平差处理按钮点击后的界面变化
logging.info("断点保存到上传列表成功,开始截图")
if not self.take_screenshot(breakpoint_name):
self.logger.error(f"设备 {device_id} 截图失败")
self.write_screenshot_status(breakpoint_name, success=False)
return False
# 检查是否重试次数用完仍未成功
if retry_count >= max_retry_attempts:
self.logger.error(f"断点 {item} 经过 {max_retry_attempts} 次重试后仍然失败")
# 重新获取当前页面项目,因为可能有新的项目加载
break
self.write_screenshot_status(breakpoint_name, success=True)
# 点击返回按钮并处理弹窗
if not self.execute_back_navigation_steps(device_id):
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
return False
# # 根据截图结果更新time.txt文件状态
# status = "ok" if all_success else "true"
# # self.update_upload_info_status(status)
# username = global_variable.get_username()
# self.update_file_status(username, "running", status)
# self.logger.info(f"{username} 截图完成状态为 {status}")
# self.logger.info(f"设备 {device_id} 截图页面操作执行完成,状态: {status}")
# return True
# 向下滑动列表以加载更多项目
if not self.scroll_list(direction="down"):
self.logger.error("向下滑动列表失败")
break
# 检查是否到达底部:连续两次获取的项目相同
if current_items == previous_items and len(current_items) > 0:
self.logger.info("连续两次获取的项目相同,已到达列表底部")
break
# 更新前一次项目集合
previous_items = current_items.copy()
scroll_count += 1
self.logger.info(f"{scroll_count} 次向下滑动,继续查找...")
# 根据截图结果更新time.txt文件状态
status = "ok" if all_success else "true"
# self.update_upload_info_status(status)
username = global_variable.get_username()
self.update_file_status(username, "running", status)
self.logger.info(f"{username} 截图完成状态为 {status}")
self.logger.info(f"设备 {device_id} 截图页面操作执行完成,状态: {status}")
# return True
# 检查是否所有断点都处理完成
if len(processed_breakpoints) == len(breakpoint_names):
self.logger.info(f"设备 {device_id} 平差页面操作执行完成")
return True
elif found_any:
self.logger.warning(f"设备 {device_id} 部分断点处理完成,已成功处理 {len(processed_breakpoints)}/{len(breakpoint_names)} 个断点")
return True
else:
self.logger.warning(f"设备 {device_id} 未找到任何目标断点")
return True
# # 开始循环
# all_success = True
# for breakpoint_name in global_variable.get_upload_breakpoint_dict().keys():
# self.logger.info(f"开始处理要平差截图的断点 {breakpoint_name}")
# # 把断点名称给find_keyword
# if not self.find_keyword(breakpoint_name):
# self.logger.error(f"设备 {device_id} 未找到包含 {breakpoint_name} 的文件名")
# all_success = False
# continue
# if not self.handle_measurement_dialog():
# self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
# all_success = False
# continue
# if not self.check_apply_btn():
# self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
# all_success = False
# self.click_back_button(device_id)
# continue
# # 根据断点名称在get_upload_breakpoint_dict()中获取线路编码
# line_code = global_variable.get_upload_breakpoint_dict().get(breakpoint_name)
# if not line_code:
# self.logger.error(f"设备 {device_id} 未找到断点 {breakpoint_name} 对应的线路编码")
# all_success = False
# continue
# # 根据线路编码查找对应的时间
# date_str, time_str = self.get_line_end_time(line_code)
# if not time_str or not date_str:
# self.logger.error(f"设备 {device_id} 未找到线路 {line_code} 对应的时间")
# all_success = False
# continue
# # 修改时间
# if not self.set_device_time(device_id, time_str, date_str):
# self.logger.error(f"设备 {device_id} 设置设备时间失败")
# all_success = False
# continue
# # 滑动列表到底部
# if not self.scroll_list_to_bottom(device_id):
# self.logger.error(f"设备 {device_id} 下滑列表到底部失败")
# all_success = False
# continue
# # 2. 点击最后一个spinner
# if not self.click_last_spinner_with_retry(device_id):
# self.logger.error(f"设备 {device_id} 点击最后一个spinner失败")
# all_success = False
# continue
# # 3. 再下滑一次
# if not self.scroll_down_once(device_id):
# self.logger.warning(f"设备 {device_id} 再次下滑失败,但继续执行")
# # 平差处理完成后截图
# time.sleep(0.2) # 等待平差处理按钮点击后的界面变化
# logging.info("断点保存到上传列表成功,开始截图")
# # png_time = date_str + " " + time_str
# if not self.take_screenshot(breakpoint_name, date_str, time_str):
# self.logger.error(f"设备 {device_id} 截图失败")
# self.write_screenshot_status(breakpoint_name, success=False)
# all_success = False
# else:
# self.write_screenshot_status(breakpoint_name, success=True)
# # 点击返回按钮并处理弹窗
# if not self.execute_back_navigation_steps(device_id):
# self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
# all_success = False
# 启用WiFi
# if not self.enable_wifi(device_id):
# self.logger.error(f"设备 {device_id} 启用WiFi失败")
# return False
self.logger.info(f"设备 {device_id} 截图页面操作执行完成")
return True
# # 根据截图结果更新time.txt文件状态
# status = "ok" if all_success else "true"
# # self.update_upload_info_status(status)
# username = global_variable.get_username()
# self.update_file_status(username, "running", status)
# self.logger.info(f"{username} 截图完成状态为 {status}")
# self.logger.info(f"设备 {device_id} 截图页面操作执行完成,状态: {status}")
# return True
except Exception as e:
self.logger.error(f"设备 {device_id} 执行截图页面操作时出错: {str(e)}")
# 保存错误截图

View File

@@ -73,7 +73,7 @@ def parse_time_config():
for line in f:
line = line.strip()
# 匹配:用户名 时间 true (仅获取待处理任务)
match = re.search(r'(\w+)\s+(\d{1,2}:\d{2}:\d{2})\s+true$', line)
match = re.search(r'(\w+)\s+(\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{2}:\d{2})\s+true$', line)
if match:
username, scheduled_time = match.group(1), match.group(2)
time_map[username] = scheduled_time
@@ -81,50 +81,101 @@ def parse_time_config():
print(f"❌ 解析 time.txt 失败: {e}")
return time_map
def get_combined_tasks():
def normalize_datetime(time_str):
"""
结合接口(is_ok==1)和本地文件(true)筛选任务
将时间字符串格式化为标准格式YYYY-MM-DD HH:MM:SS
补全单数字的月、日、时
例如2024-1-15 9:52:20 -> 2024-01-15 09:52:20
"""
try:
local_times = parse_time_config()
if not local_times:
return {}
# 分割日期和时间部分
if ' ' in time_str:
date_part, time_part = time_str.split(' ', 1)
# 补全日期部分的单数字
date_parts = date_part.split('-')
if len(date_parts) == 3:
year = date_parts[0]
month = date_parts[1].zfill(2) # 月补零
day = date_parts[2].zfill(2) # 日补零
date_part = f"{year}-{month}-{day}"
# 补全时间部分的单数字小时
time_parts = time_part.split(':')
if len(time_parts) >= 1:
hour = time_parts[0].zfill(2) # 小时补零
time_part = f"{hour}:{':'.join(time_parts[1:])}"
return f"{date_part} {time_part}"
return time_str
except Exception as e:
print(f"⚠️ 时间格式标准化失败 ({time_str}): {e}")
return time_str
def get_combined_tasks():
"""
# 结合接口(is_ok==1)和本地文件(true)筛选任务
结合接口(is_ok==1)和获取解析云端轨迹文件筛选任务
"""
try:
# 调用你的 API 接口获取账号信息
accounts = apis.get_accounts_from_server("68c0dbfdb7cbcd616e7c5ab5")
accounts = apis.get_accounts_from_server("68ef0e02b0138d25e2ac9918")
if not accounts:
return {}
task_list = {}
today = datetime.now().strftime("%Y-%m-%d")
today = datetime.now().strftime("%Y%m%d")
for account in accounts:
if account.get('is_ok') == 1 or account.get('username') == "czyuzongwen":
if account.get('is_ok') == 1:
user = account.get('username')
ip = account.get('device_ip')
port = account.get('device_port')
project_name = account.get('project_name')
# 只有在 time.txt 中是 true 的账号才会被加入
if user in local_times and ip and port:
address = f"{ip}:{port}"
# full_time = f"{today} {local_times[user]}"
# 确保时间是两位数格式
raw_time = local_times[user]
# 将时间格式化为两位数9:52:20 -> 09:52:20
if ':' in raw_time:
parts = raw_time.split(':')
if len(parts[0]) == 1:
raw_time = f"0{raw_time}" # 补齐前导零
# 获取轨迹文件
save_path = apis.fetch_and_save_track_file(f"https://database.yuxindazhineng.com/team-bucket/69378c5b4f42d83d9504560d/track/{today}/{today}_1_{user}.txt")
if save_path:
full_time = f"{today} {raw_time}"
task_list[address] = {"time": full_time, "user": user}
# 1. 解析原始文件
raw_records = apis.parse_track_file(save_path)
# 2. 按线路ID去重重复则保留后面的记录
deduplicated_records = apis.deduplicate_by_line_id(raw_records)
# 3. 从去重后的记录中找最晚结束时间
latest_time = apis.get_latest_end_time(deduplicated_records)
# 4. 写入end.txt
# write_success = apis.write_to_file(latest_time)
write_success = apis.writer_file_status(user, latest_time, "true")
time.sleep(2)
# 获取状态为true的账号
local_times = parse_time_config()
if not local_times:
return {}
# 只有在写入成功且 time.txt 中是 true 的账号才会被加入
if write_success and user in local_times and ip and port:
address = f"{ip}:{port}"
# 确保时间是两位数格式
raw_time = local_times[user]
full_time = normalize_datetime(raw_time)
task_list[address] = {"time": full_time, "user": user, "project_name": project_name}
elif not write_success:
print(f"❌ 写入end.txt失败跳过任务: {user}")
return task_list
except Exception as e:
print(f"❌ 获取任务异常: {e}")
return {}
def run_task(address, target_time, username):
def run_task(address, target_time, username, project_name):
"""
单个执行线程:锁定状态 -> 等待 -> 执行 -> 完成
"""
@@ -133,20 +184,20 @@ def run_task(address, target_time, username):
if not update_file_status(username, "true", "running"):
return f"⏭️ {username} 状态已变更,跳过执行。"
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time} | 项目: {project_name}")
try:
# 2. 计算并执行等待逻辑
target_dt = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S")
wait_secs = (target_dt - datetime.now()).total_seconds()
# target_dt = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S")
# wait_secs = (target_dt - datetime.now()).total_seconds()
if wait_secs > 0:
print(f"{username} 距离执行还有 {int(wait_secs)} 秒...")
time.sleep(wait_secs)
# if wait_secs > 0:
# print(f"⏳ {username} 距离执行还有 {int(wait_secs)} 秒...")
# time.sleep(wait_secs)
# 3. 调用 main.py 中的自动化逻辑
print(f"▶️ [正在执行] {username} 开始自动化操作...")
automation = DeviceAutomation(address)
automation = DeviceAutomation(address, project_name)
result = automation.handle_app_state()
# 4. 执行完成后,将状态从 running 改为 done
@@ -169,9 +220,9 @@ def monitor_center():
if tasks:
print(f"📡 发现 {len(tasks)} 个符合条件且未跑过的任务,准备启动线程池...")
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
# 提交任务,将 address, time, username 传入
# 提交任务,将 address, time, username, project_name 传入
future_to_user = {
executor.submit(run_task, addr, info['time'], info['user']): info['user']
executor.submit(run_task, addr, info['time'], info['user'], info.get('project_name', '')): info['user']
for addr, info in tasks.items()
}
@@ -191,3 +242,4 @@ if __name__ == "__main__":
monitor_center()
except KeyboardInterrupt:
print("\n👋 用户手动停止程序。")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

View File

@@ -22,7 +22,7 @@ exe = EXE(
a.binaries,
a.datas,
[],
name='沉降观测自动上传',
name='沉降观测自动截图',
debug=False,
bootloader_ignore_signals=False,
strip=False,

View File

@@ -2,7 +2,7 @@
a = Analysis(
['create_a_link.py'],
['get_line_code.py'],
pathex=[],
binaries=[],
datas=[],
@@ -22,7 +22,7 @@ exe = EXE(
a.binaries,
a.datas,
[],
name='create_a_link',
name='自动导轨迹',
debug=False,
bootloader_ignore_signals=False,
strip=False,