cadb
Version:
安卓/鸿蒙系统截图/录屏工具
194 lines (178 loc) • 5.74 kB
JavaScript
/**
* Created by Niki on 2025/2/11 11:19.
* Email: m13296644326@163.com
*/
const program = require('commander');
const {execFileSync, execFile, exec} = require('child_process');
const _ = require('lodash');
const fs = require('fs');
const {
getCurrentWifiName,
isHarmonyDeviceConnected,
chooseHarmonyRealDeviceId,
hdcPath,
collectUserInput,
adbPath,
} = require('../common/utils');
const {logRed, shellConfigs, logGreen} = require('../common/constants');
const {rcPath} = require('../common/utils');
let rcConfig = {};
let newIpCacheItem = {};
const port = 35402;
program
.option('-c --noCache', 'drop device ip cache')
.option('-kill --killConnection', 'kill tcp connection')
.option('-ls --ls', 'review all connected devices')
.action(args => {
run(args);
})
.parse(process.argv);
// todo 当前仅支持鸿蒙
async function run(args) {
const {killConnection, ls} = args;
if (ls) {
lsDevices();
return;
}
const dList = checkHarmonyLocalConnected();
const realDeviceCmd = await chooseHarmonyRealDeviceId(dList, true);
const deviceIp = await collectDeviceIp(args, realDeviceCmd);
if (killConnection) {
disconnected(realDeviceCmd, deviceIp);
return;
}
await openPort(realDeviceCmd);
connectDevice(realDeviceCmd, deviceIp);
}
// 是否已通过usb连接
function checkHarmonyLocalConnected() {
const dList = isHarmonyDeviceConnected() || [];
// 判断是否是真机
const localConnected = dList.some(
t => !t.includes(':') && !t.startsWith('127.0.0.1'),
);
if (!localConnected) {
logRed('当前没有鸿蒙设备通过usb连接');
process.exit();
}
return dList;
}
function openPort(realDeviceCmd) {
let idParamList = [];
if (realDeviceCmd) {
idParamList = realDeviceCmd.split(' ');
}
return new Promise((resolve, rej) => {
const openCdm = [...idParamList, 'tmode', 'port', port];
console.log('execute:', `hdc ${openCdm.join(' ')}`);
const stdOut = execFileSync(hdcPath, openCdm, shellConfigs);
console.log(stdOut);
setTimeout(() => {
resolve();
}, 900);
if (!stdOut.includes('successful')) {
process.exit();
}
});
}
// 收集客户端ip; todo 支持 -c参数, 以重置客户端ip
async function collectDeviceIp(args, realDeviceCmd) {
const {noCache} = args;
const deviceId = realDeviceCmd.split(' ')[1].trim();
const wifiName = getCurrentWifiName();
if (!fs.existsSync(rcPath)) {
fs.writeFileSync(rcPath, JSON.stringify({}));
} else {
rcConfig = JSON.parse(fs.readFileSync(rcPath, 'utf-8'));
}
const {deviceIpCacheList = []} = rcConfig;
let originIsEmpty = true;
let deviceIp = '';
if (noCache) {
deviceIp = await collectDeviceIpWithInput();
} else {
const find = _.find(deviceIpCacheList, {deviceId, wifiName});
if (find && find.deviceIp) {
deviceIp = find.deviceIp;
originIsEmpty = false;
} else {
deviceIp = await collectDeviceIpWithInput();
}
}
newIpCacheItem = {deviceId, wifiName, deviceIp};
writeIpCache(originIsEmpty);
return deviceIp;
}
// 确定连接成功后才写入缓存
function writeIpCache(originIsEmpty) {
const {deviceId, wifiName, deviceIp} = newIpCacheItem;
const {deviceIpCacheList = []} = rcConfig;
_.remove(deviceIpCacheList, {deviceId, wifiName});
deviceIpCacheList.push({deviceId, wifiName, deviceIp});
rcConfig.deviceIpCacheList = deviceIpCacheList;
fs.writeFileSync(rcPath, JSON.stringify(rcConfig));
if (originIsEmpty) {
logGreen(`ip地址已写入缓存: ${JSON.stringify(newIpCacheItem)}`);
}
}
async function collectDeviceIpWithInput() {
console.log('\r\n请输入手机设备的ip: ');
const ipPattern =
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const rawIp = await collectUserInput();
if (!ipPattern.test(rawIp)) {
logRed('请输入正确的ivp4 ip地址');
process.exit();
}
return rawIp;
}
function connectDevice(realDeviceCmd, deviceIp) {
let idParamList = [];
if (realDeviceCmd) {
idParamList = realDeviceCmd.split(' ');
}
const connectCmd = [...idParamList, 'tconn', `${deviceIp}:${port}`];
console.log('execute:', `hdc ${connectCmd.join(' ')}`);
const timeOutTask = setTimeout(() => {
logRed('tcp connect timeout, 请检查下列状况:\r\n');
console.log('1.手机设备是否可以上网且跟电脑处于同一wifi');
console.log('2.手机wifi的ip是否已经改变, 可执行 cadb connect -c 更改ip');
console.log('3.电脑若使用DEV wifi, 请关闭aTrust vpn');
console.log(`4.可执行 ping ${deviceIp} 检测tcp 通道`);
console.log('\r\n');
process.exit(1);
}, 2000);
execFile(hdcPath, connectCmd, shellConfigs, (error, stdout, stderr) => {
if (stdout) {
console.log(stdout);
clearTimeout(timeOutTask);
if (stdout.includes('Connect OK')) {
// writeIpCache();
logGreen('连接成功\r\n');
}
} else if (stderr) {
console.log(stderr);
}
});
}
function disconnected(realDeviceCmd, deviceIp) {
let idParamList = [];
if (realDeviceCmd) {
idParamList = realDeviceCmd.split(' ');
}
const disconnectCmd = [
...idParamList,
'tconn',
`${deviceIp}:${port}`,
'-remove',
];
console.log('execute:', `hdc ${disconnectCmd.join(' ')}`);
const stdout = execFileSync(hdcPath, disconnectCmd, shellConfigs);
console.log(stdout);
}
function lsDevices() {
console.log('鸿蒙:');
console.log(execFileSync(hdcPath, ['list', 'targets'], shellConfigs));
console.log('\r\n安卓:');
console.log(execFileSync(adbPath, ['devices'], shellConfigs));
}