/** * 测试通过 WebSocket 连接微信开发者工具自动化 * 自动化 token: 0c61f39a3e1e23e6721182b5e9913c1b */ const http = require('http'); const net = require('net'); const path = require('path'); const fs = require('fs'); const PORT = 16866; const TOKEN = '0c61f39a3e1e23e6721182b5e9913c1b'; function httpReq(port, path) { return new Promise((resolve) => { http.get(`http://127.0.0.1:${port}${path}`, { timeout: 5000 }, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve({ status: res.statusCode, data })); }).on('error', (err) => resolve({ status: 0, data: err.message })); }); } async function main() { // 1. 尝试 /json/version 和 /json 在 16866 端口 console.log('=== 测试 16866 端口的 DevTools Protocol 端点 ==='); for (const ep of ['/json/version', '/json', '/json/list', `/json/${TOKEN}`]) { const r = await httpReq(PORT, ep); console.log(` ${ep} → [${r.status}] ${r.data.substring(0, 200)}`); } // 2. 尝试用 automator.connect() 连接 console.log('\n=== 尝试 automator.connect() ==='); const npxCacheBase = path.join(process.env.LOCALAPPDATA, 'npm-cache', '_npx'); let automatorPath = null; for (const dir of fs.readdirSync(npxCacheBase)) { const candidate = path.join(npxCacheBase, dir, 'node_modules', 'miniprogram-automator'); if (fs.existsSync(candidate)) { automatorPath = candidate; break; } } if (!automatorPath) { console.error('未找到 automator'); return; } const automator = require(automatorPath); // 尝试各种 wsEndpoint 格式 const wsEndpoints = [ `ws://127.0.0.1:${PORT}`, `ws://127.0.0.1:${PORT}/${TOKEN}`, `ws://127.0.0.1:${PORT}/devtools/page/${TOKEN}`, `ws://127.0.0.1:${PORT}/devtools/browser/${TOKEN}`, ]; for (const ws of wsEndpoints) { console.log(`\n尝试 connect({ wsEndpoint: "${ws}" })`); try { const mp = await Promise.race([ automator.connect({ wsEndpoint: ws }), new Promise((_, reject) => setTimeout(() => reject(new Error('5s 超时')), 5000)) ]); console.log('✅ 连接成功!'); const page = await mp.currentPage(); console.log('当前页面:', page ? page.path : '无'); await mp.close(); return; // 成功就退出 } catch (err) { console.log(` ❌ ${err.message}`); } } // 3. 全范围端口扫描(更宽) console.log('\n=== 全范围端口扫描 (1000-65535 采样) ==='); // 扫描常见范围 const ranges = [ [8000, 8100], [9000, 9999], [16000, 17000], [19000, 20000], [30000, 31000], [40000, 41000], ]; for (const [start, end] of ranges) { const promises = []; for (let p = start; p <= end; p++) { promises.push(new Promise((resolve) => { const socket = new net.Socket(); socket.setTimeout(500); socket.on('connect', () => { socket.destroy(); resolve(p); }); socket.on('timeout', () => { socket.destroy(); resolve(null); }); socket.on('error', () => { socket.destroy(); resolve(null); }); socket.connect(p, '127.0.0.1'); })); } const open = (await Promise.all(promises)).filter(Boolean); if (open.length > 0) { console.log(` ${start}-${end}: ${open.join(', ')}`); // 对每个开放端口测试 /json/version for (const p of open) { if (p === PORT) continue; const r = await httpReq(p, '/json/version'); if (r.status === 200) console.log(` ${p} /json/version: ${r.data.substring(0, 150)}`); } } } } const timer = setTimeout(() => { console.error('总超时'); process.exit(1); }, 60000); main().then(() => { clearTimeout(timer); process.exit(0); });