{“content”:”---\nname: windows-pc-ssh-screen-capture-limitation\ncategory: windows-pc\ndescription: SSH 到 Windows PC 时 mss 截图只能捕获虚拟显示(Session 0),无法截取用户真实桌面\n---\n\n# Windows PC SSH Screen Capture Limitation\n\n## Problem\nWhen running Python scripts via SSH to a Windows PC (e.g., ssh [email protected] 'python ...'), the script executes in Session 0 (the Windows services/logon session), not the active user desktop session.\n\nThis means screen capture tools like mss capture a virtual display (typically 1024x768), not the real user desktop.\n\n## Verified Symptoms\n- mss.mss().monitors[1] returns {'left': 0, 'top': 0, 'width': 1024, 'height': 768} — virtual screen\n- Screenshots are ~2-5KB (tiny, mostly blank)\n- User desktop apps, windows, RustDesk UI are NOT visible in captures\n- PyAutoGUI commands (click, move, type) CAN be executed via SSH and DO work on the user desktop — they just can’t “see” it\n\n## Why This Happens\nWindows Session 0 isolation: SSH sessions spawn processes in Session 0, which has no graphical access to the user desktop. Tools like mss, PIL.ImageGrab need a display to capture.\n\n## ⚠️ Critical: ALL GUI Apps Are Invisible via SSH\n\nThis is NOT just a screenshot problem — any GUI application started via SSH runs in Session 0 and is completely invisible to the logged-in user, including:\n- PyBoy with window=\"SDL2\" — window opens in Session 0, user sees nothing\n- Any Start-Process GUI application\n- Any Python script that opens a window (tkinter, pygame, etc.)\n\nThe implication: If the user needs to SEE the result (game window, GUI app), SSH is fundamentally the wrong tool. Workarounds:\n\n1. User runs commands manually on the PC (e.g., user opens CMD and runs the script directly)\n2. Chrome Remote Desktop — gives full access to the real user desktop session\n3. VNC/RustDesk — user controls their own session while agent automates\n\nFile paths: Always use D: prefix per user preference (D:\pokemon-agent, D:\projects, etc.)\n\n## Workarounds (Partial)\n1. Task Scheduler with user context: schtasks /create /tn TaskName /tr \"python script.py\" /sc onlogon /rl limited — runs as logged-in user, but still might face session mismatch\n2. RustDesk as relay: RustDesk runs in user session; use its API/automation to capture screenshots there\n3. Accept virtual screen: Use for server/HMI automation, not for user desktop control\n4. Manual screenshot trigger: User manually saves screenshot to a shared folder\n\n## Other Quirks Discovered\n- powershell -Command \"Set-Content ...\" adds UTF-8 BOM → use [System.IO.File]::WriteAllText() or base64 decode approach for BOM-free files\n- mss.mss().save() in mss 10.x returns a generator → use mss.mss().shot() instead which returns a filename string\n- SSH to Windows with scp works; file appears as 0 bytes in some ls outputs but transfers correctly\n\n## PC Info\n- Host: 100.83.112.84 (sozo)\n- Python: C:\\Users\\Sozo\\AppData\\Local\\Programs\\Python\\Python311\\python.exe\n- Installed: pyautogui 0.9.54, mss 10.1.0, pillow 12.1.1\n- hermes dir: C:\\Users\\sozo\\hermes\\\n”}