getip.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/env node
  2. const { execSync } = require('child_process')
  3. const path = require('path')
  4. // 项目根:bat-tool/getip -> 上两级;打包时若在 app.asar 内则用 app.asar.unpacked
  5. let PROJECT_ROOT = path.resolve(__dirname, '..', '..')
  6. if (PROJECT_ROOT.includes('app.asar') && !PROJECT_ROOT.includes('app.asar.unpacked')) {
  7. PROJECT_ROOT = PROJECT_ROOT.replace('app.asar', 'app.asar.unpacked')
  8. }
  9. function getAdbPath() {
  10. const configPath = path.join(PROJECT_ROOT, 'configs', 'config.js')
  11. const config = require(configPath)
  12. return config.adbPath?.path
  13. ? path.resolve(PROJECT_ROOT, config.adbPath.path)
  14. : path.join(PROJECT_ROOT, 'lib', 'scrcpy-adb', 'adb.exe')
  15. }
  16. function getConnectedDeviceIds(adbPath) {
  17. const out = execSync(`"${adbPath}" devices`, { encoding: 'utf-8' })
  18. return out
  19. .split('\n')
  20. .filter((line) => line.trim() && !line.startsWith('List') && line.includes('\tdevice'))
  21. .map((line) => line.trim().split('\t')[0])
  22. .filter((id) => id && !id.includes(':'))
  23. }
  24. function parseInetFromOutput(out, skipLoopback = false) {
  25. const re = /inet\s+(\d+\.\d+\.\d+\.\d+)/g
  26. const ips = []
  27. let m
  28. while ((m = re.exec(out || '')) !== null) ips.push(m[1])
  29. if (ips.length === 0) return null
  30. if (skipLoopback) {
  31. const nonLoop = ips.find((ip) => ip !== '127.0.0.1')
  32. return nonLoop || null
  33. }
  34. return ips[0]
  35. }
  36. function adbShellCmd(adbPath, deviceId, shellCmd) {
  37. const id = deviceId.indexOf(' ') >= 0 ? `"${deviceId}"` : deviceId
  38. return `"${adbPath}" -s ${id} shell ${shellCmd}`
  39. }
  40. function getDeviceIp(adbPath, deviceId) {
  41. const run = (shellCmd) => {
  42. try {
  43. return execSync(adbShellCmd(adbPath, deviceId, shellCmd), { encoding: 'utf-8' })
  44. } catch (e) {
  45. return ''
  46. }
  47. }
  48. let out = run('ip -4 addr show wlan0')
  49. let ip = parseInetFromOutput(out)
  50. if (ip) return ip
  51. out = run('ip -4 addr show eth0')
  52. ip = parseInetFromOutput(out)
  53. if (ip) return ip
  54. out = run('ip route get 1.1.1.1')
  55. let m = out.match(/\bsrc\s+(\d+\.\d+\.\d+\.\d+)\b/)
  56. if (m) return m[1]
  57. m = out.match(/\bfrom\s+(\d+\.\d+\.\d+\.\d+)\b/)
  58. if (m) return m[1]
  59. for (const prop of ['dhcp.wlan0.ipaddress', 'net.wlan0.ipaddress', 'dhcp.eth0.ipaddress']) {
  60. out = run('getprop ' + prop)
  61. ip = (out || '').trim()
  62. if (/^\d+\.\d+\.\d+\.\d+$/.test(ip)) return ip
  63. }
  64. out = run('ip -4 addr show')
  65. return parseInetFromOutput(out, true)
  66. }
  67. function run() {
  68. const adbPath = getAdbPath()
  69. const devices = getConnectedDeviceIds(adbPath)
  70. if (devices.length === 0) {
  71. process.stderr.write('No devices found. Please connect a device via USB.\n')
  72. process.exit(1)
  73. }
  74. const deviceId = devices[0]
  75. const ip = getDeviceIp(adbPath, deviceId)
  76. if (ip) {
  77. process.stdout.write(ip + '\n')
  78. process.exit(0)
  79. }
  80. process.stderr.write('Could not get device IP. Check WiFi on device.\n')
  81. process.exit(1)
  82. }
  83. run()