/** * 端口检测和清理脚本 * 启动服务前检查并清理占用端口的进程 */ const { exec, spawn } = require('child_process'); const netstat = (cmd) => new Promise((resolve) => { exec(cmd, { shell: true }, (err, stdout) => resolve(stdout)); }); const PORTS = [ { port: 8003, name: 'Backend' }, { port: 9001, name: 'Frontend' }, ]; async function getProcessesUsingPort(port) { try { const output = await netstat(`netstat -ano | findstr :${port}`); const lines = output.trim().split('\n').filter(Boolean); const pids = new Set(); for (const line of lines) { const parts = line.trim().split(/\s+/); const localAddress = parts[1] || ''; if (localAddress.includes(`:${port}`)) { const pid = parts[4] || parts[3]; if (pid && pid !== '0' && /^\d+$/.test(pid)) { pids.add(pid); } } } return [...pids]; } catch { return []; } } async function killProcess(pid) { return new Promise((resolve) => { exec(`taskkill /F /PID ${pid}`, (err, stdout) => { resolve({ pid, success: !err, output: stdout }); }); }); } async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function checkAndKillPorts() { console.log('🔍 检查端口占用情况...\n'); for (const { port, name } of PORTS) { const pids = await getProcessesUsingPort(port); if (pids.length > 0) { console.log(`⚠️ ${name} 端口 ${port} 被占用 (PID: ${pids.join(', ')}), 正在清理...`); for (const pid of pids) { await killProcess(pid); } await sleep(500); // 等待进程完全退出 console.log(`✅ 端口 ${port} 已清理\n`); } else { console.log(`✅ 端口 ${port} 空闲`); } } console.log('\n🚀 启动服务...\n'); } const command = process.argv[2]; const args = process.argv.slice(3); checkAndKillPorts().then(() => { if (command) { const child = spawn(command, args, { stdio: 'inherit', shell: true, }); child.on('error', (err) => { console.error('启动失败:', err); process.exit(1); }); child.on('close', (code) => { process.exit(code || 0); }); } else { console.log('用法: node scripts/check-ports.js [args...]'); process.exit(0); } });