- WebSocket relay service (FastAPI) bridges agents and viewers - Python agent with screen capture (mss), input control (pynput), script execution, and auto-reconnect - Windows service wrapper, PyInstaller spec, NSIS installer for silent mass deployment (RemoteLink-Setup.exe /S /SERVER= /ENROLL=) - Enrollment token system: admin generates tokens, agents self-register - Real WebSocket viewer replaces simulated canvas - Linux agent binary served from /downloads/remotelink-agent-linux - DB migration 0002: viewer_token on sessions, enrollment_tokens table - Sign-up pages cleaned up (invite-only redirect) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
111 lines
2.5 KiB
Python
111 lines
2.5 KiB
Python
# PyInstaller spec for RemoteLink Agent
|
|
# Build: pyinstaller agent.spec
|
|
|
|
import sys
|
|
from PyInstaller.utils.hooks import collect_data_files, collect_submodules
|
|
|
|
block_cipher = None
|
|
|
|
# Collect mss data files (monitor detection)
|
|
mss_datas = collect_data_files('mss')
|
|
|
|
a = Analysis(
|
|
['agent.py'],
|
|
pathex=[],
|
|
binaries=[],
|
|
datas=mss_datas,
|
|
hiddenimports=[
|
|
'mss',
|
|
'mss.windows',
|
|
'mss.darwin',
|
|
'mss.linux',
|
|
'PIL',
|
|
'PIL.Image',
|
|
'PIL.JpegImagePlugin',
|
|
'pynput',
|
|
'pynput.mouse',
|
|
'pynput.keyboard',
|
|
'pynput._util',
|
|
'pynput._util.win32',
|
|
'pynput._util.darwin',
|
|
'pynput._util.xorg',
|
|
'websockets',
|
|
'websockets.legacy',
|
|
'websockets.legacy.client',
|
|
'httpx',
|
|
'httpcore',
|
|
'asyncio',
|
|
'json',
|
|
'logging',
|
|
'platform',
|
|
'subprocess',
|
|
'signal',
|
|
],
|
|
hookspath=[],
|
|
runtime_hooks=[],
|
|
excludes=['tkinter', 'matplotlib', 'numpy', 'scipy'],
|
|
win_no_prefer_redirects=False,
|
|
win_private_assemblies=False,
|
|
cipher=block_cipher,
|
|
noarchive=False,
|
|
)
|
|
|
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
|
|
# Single-file portable executable
|
|
exe = EXE(
|
|
pyz,
|
|
a.scripts,
|
|
a.binaries,
|
|
a.zipfiles,
|
|
a.datas,
|
|
[],
|
|
name='remotelink-agent',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=True,
|
|
upx_exclude=[],
|
|
runtime_tmpdir=None,
|
|
console=False, # No console window (set True for debugging)
|
|
disable_windowed_traceback=False,
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
icon='assets/icon.ico' if sys.platform == 'win32' else None,
|
|
version='version_info.txt' if sys.platform == 'win32' else None,
|
|
)
|
|
|
|
# Windows service executable (separate build target)
|
|
svc_a = Analysis(
|
|
['service_win.py'],
|
|
pathex=[],
|
|
binaries=[],
|
|
datas=mss_datas,
|
|
hiddenimports=[
|
|
'win32serviceutil', 'win32service', 'win32event', 'servicemanager',
|
|
'agent',
|
|
] + collect_submodules('win32'),
|
|
hookspath=[],
|
|
runtime_hooks=[],
|
|
excludes=['tkinter'],
|
|
cipher=block_cipher,
|
|
)
|
|
|
|
svc_pyz = PYZ(svc_a.pure, svc_a.zipped_data, cipher=block_cipher)
|
|
|
|
svc_exe = EXE(
|
|
svc_pyz,
|
|
svc_a.scripts,
|
|
svc_a.binaries,
|
|
svc_a.zipfiles,
|
|
svc_a.datas,
|
|
[],
|
|
name='remotelink-agent-service',
|
|
debug=False,
|
|
strip=False,
|
|
upx=True,
|
|
console=True,
|
|
icon='assets/icon.ico' if sys.platform == 'win32' else None,
|
|
)
|