mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2024-11-15 03:07:41 +01:00
fix: 🔨 修复直接进行无线连接时没有处理配对设备的问题
This commit is contained in:
parent
2371b26d6a
commit
4263d07076
2
.github/workflows/release-assets.yml
vendored
2
.github/workflows/release-assets.yml
vendored
@ -54,4 +54,4 @@ jobs:
|
||||
dist/*.yml
|
||||
dist/*.blockmap
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -17,4 +17,4 @@ jobs:
|
||||
with:
|
||||
release-type: node
|
||||
package-name: release-please-action
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
|
@ -1,3 +1,4 @@
|
||||
provider: generic
|
||||
url: https://example.com/auto-updates
|
||||
provider: github
|
||||
owner: viarotel-org
|
||||
repo: escrcpy
|
||||
updaterCacheDirName: escrcpy-updater
|
||||
|
@ -45,5 +45,6 @@ appImage:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
npmRebuild: false
|
||||
publish:
|
||||
provider: generic
|
||||
url: https://example.com/auto-updates
|
||||
provider: github
|
||||
owner: viarotel-org
|
||||
repo: escrcpy
|
||||
|
@ -19,7 +19,7 @@ function createWindow() {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
icon,
|
||||
minWidth: 900,
|
||||
minWidth: 1000,
|
||||
minHeight: 700,
|
||||
show: false,
|
||||
autoHideMenuBar: true,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { app, ipcMain } from 'electron'
|
||||
import './updater/index.js'
|
||||
|
||||
ipcMain.on('restart-app', () => {
|
||||
app.relaunch()
|
||||
|
90
src/main/ipc/updater/index.js
Normal file
90
src/main/ipc/updater/index.js
Normal file
@ -0,0 +1,90 @@
|
||||
import { app, dialog, ipcMain } from 'electron'
|
||||
import { is } from '@electron-toolkit/utils'
|
||||
import { autoUpdater } from 'electron-updater'
|
||||
|
||||
const path = require('node:path')
|
||||
|
||||
// dev-start, 这里是为了在本地做应用升级测试使用,正式环境请务必删除
|
||||
if (is.dev && process.env.ELECTRON_RENDERER_URL) {
|
||||
autoUpdater.updateConfigPath = path.join(__dirname, '../../../../dev-app-update.yml')
|
||||
}
|
||||
|
||||
Object.defineProperty(app, 'isPackaged', {
|
||||
get() {
|
||||
return true
|
||||
},
|
||||
})
|
||||
// dev-end
|
||||
|
||||
// 触发检查更新(此方法用于被渲染线程调用,例如页面点击检查更新按钮来调用此方法)
|
||||
ipcMain.on('check-for-update', () => {
|
||||
console.log('触发检查更新')
|
||||
autoUpdater.checkForUpdates()
|
||||
})
|
||||
|
||||
// 设置自动下载为false(默认为true,检测到有更新就自动下载)
|
||||
autoUpdater.autoDownload = false
|
||||
// 检测下载错误
|
||||
autoUpdater.on('error', (error) => {
|
||||
console.error('更新异常', error)
|
||||
})
|
||||
|
||||
// 检测是否需要更新
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
console.log('正在检查更新……')
|
||||
})
|
||||
// 检测到可以更新时
|
||||
autoUpdater.on('update-available', (releaseInfo) => {
|
||||
console.log('检测到新版本,确认是否下载')
|
||||
const releaseNotes = releaseInfo.releaseNotes
|
||||
let releaseContent = ''
|
||||
if (releaseNotes) {
|
||||
if (typeof releaseNotes === 'string') {
|
||||
releaseContent = releaseNotes
|
||||
}
|
||||
else if (Array.isArray(releaseNotes)) {
|
||||
releaseNotes.forEach((releaseNote) => {
|
||||
releaseContent += `${releaseNote}\n`
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
releaseContent = '暂无更新说明'
|
||||
}
|
||||
// 弹框确认是否下载更新(releaseContent是更新日志)
|
||||
dialog
|
||||
.showMessageBox({
|
||||
type: 'info',
|
||||
title: '应用有新的更新',
|
||||
detail: releaseContent,
|
||||
message: '发现新版本,是否现在更新?',
|
||||
buttons: ['否', '是'],
|
||||
})
|
||||
.then(({ response }) => {
|
||||
if (response === 1) {
|
||||
// 下载更新
|
||||
autoUpdater.downloadUpdate()
|
||||
}
|
||||
})
|
||||
})
|
||||
// 检测到不需要更新时
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
console.log('现在使用的就是最新版本,不用更新')
|
||||
})
|
||||
// 更新下载进度
|
||||
autoUpdater.on('download-progress', (progress) => {
|
||||
console.log('下载进度', progress)
|
||||
})
|
||||
// 当需要更新的内容下载完成后
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
console.log('下载完成,准备更新')
|
||||
dialog
|
||||
.showMessageBox({
|
||||
title: '安装更新',
|
||||
message: '更新下载完毕,应用将重启并进行安装',
|
||||
})
|
||||
.then(() => {
|
||||
// 退出并安装应用
|
||||
setImmediate(() => autoUpdater.quitAndInstall())
|
||||
})
|
||||
})
|
@ -12,17 +12,34 @@ window.addEventListener('beforeunload', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const shell = async command => exec(`${adbPath} ${command}`)
|
||||
const getDevices = async () => await client.listDevicesWithPaths()
|
||||
const shell = async (id, command) => await client.getDevice(id).shell(command)
|
||||
const rawShell = async command => exec(`${adbPath} ${command}`)
|
||||
const deviceShell = async (id, command) => await client.getDevice(id).shell(command)
|
||||
const kill = async (...params) => await client.kill(...params)
|
||||
const connect = async (...params) => await client.connect(...params)
|
||||
const disconnect = async (...params) => await client.disconnect(...params)
|
||||
|
||||
const getDeviceIP = async (id) => {
|
||||
try {
|
||||
const { stdout } = await shell(`-s ${id} shell ip -f inet addr show wlan0`)
|
||||
// console.log('stdout', stdout)
|
||||
const reg = /inet ([0-9.]+)\/\d+/
|
||||
const match = stdout.match(reg)
|
||||
const value = match[1]
|
||||
return value
|
||||
}
|
||||
catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const tcpip = async (id, port = 5555) => await client.getDevice(id).tcpip(port)
|
||||
|
||||
const watch = async (callback) => {
|
||||
const tracker = await client.trackDevices()
|
||||
tracker.on('add', (device) => {
|
||||
callback('add', device)
|
||||
tracker.on('add', async (ret) => {
|
||||
const host = await getDeviceIP(ret.id)
|
||||
callback('add', { ...ret, $host: host })
|
||||
})
|
||||
|
||||
tracker.on('remove', (device) => {
|
||||
@ -47,12 +64,14 @@ export default () => {
|
||||
console.log('client', client)
|
||||
|
||||
return {
|
||||
getDevices,
|
||||
shell,
|
||||
rawShell,
|
||||
getDevices,
|
||||
deviceShell,
|
||||
kill,
|
||||
connect,
|
||||
disconnect,
|
||||
watch,
|
||||
getDeviceIP,
|
||||
tcpip,
|
||||
}
|
||||
}
|
||||
|
90
src/renderer/src/components/Devices/PairDialog/index.vue
Normal file
90
src/renderer/src/components/Devices/PairDialog/index.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="无线配对" width="600" append-to-body>
|
||||
<div class="text-red-500 text-sm pb-8 pl-4">
|
||||
注意:可以在 开发者选项 -> 无线调试(可以点进去) -> 使用配对码配对设备 中获取以下信息
|
||||
</div>
|
||||
|
||||
<el-form :model="formData" label-width="100px">
|
||||
<el-form-item label="配对IP地址" prop="host">
|
||||
<el-input v-model="formData.host" placeholder="请输入配对IP地址" class="" clearable>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="配对端口号" prop="port">
|
||||
<el-input
|
||||
v-model.number="formData.port"
|
||||
type="number"
|
||||
placeholder="请输入配对端口号"
|
||||
:min="0"
|
||||
clearable
|
||||
class=""
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="配对码"
|
||||
prop="pair"
|
||||
:rules="[{ required: true, message: '配对码不能为空' }]"
|
||||
>
|
||||
<el-input
|
||||
v-model.number="formData.pair"
|
||||
type="number"
|
||||
placeholder="请输入配对码"
|
||||
:min="0"
|
||||
clearable
|
||||
class=""
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['success'],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
formData: {
|
||||
host: '',
|
||||
port: '',
|
||||
pair: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show({ params = {} } = {}) {
|
||||
this.formData = {
|
||||
...this.$options.data().formData,
|
||||
host: params.host,
|
||||
}
|
||||
this.visible = true
|
||||
},
|
||||
handleClose() {
|
||||
this.visible = false
|
||||
},
|
||||
async handleSubmit() {
|
||||
try {
|
||||
const command = `pair ${this.formData.host}:${this.formData.port} ${this.formData.pair}`
|
||||
// console.log(command)
|
||||
await this.$adb.rawShell(command)
|
||||
this.$emit('success')
|
||||
this.handleClose()
|
||||
}
|
||||
catch (error) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="flex items-center flex-none space-x-2">
|
||||
<el-input v-model="formData.host" placeholder="192.168.0.1" class="w-86" clearable>
|
||||
<el-input v-model="formData.host" placeholder="192.168.0.1" class="w-86 flex-none" clearable>
|
||||
<template #prepend>
|
||||
无线连接
|
||||
</template>
|
||||
@ -15,7 +15,7 @@
|
||||
placeholder="5555"
|
||||
:min="0"
|
||||
clearable
|
||||
class="w-32"
|
||||
class="w-32 flex-none"
|
||||
>
|
||||
</el-input>
|
||||
|
||||
@ -68,6 +68,9 @@
|
||||
<el-button type="primary" :loading="row.$loading" @click="handleMirror(row)">
|
||||
{{ row.$loading ? '镜像中' : '开始镜像' }}
|
||||
</el-button>
|
||||
<el-button v-if="!row.$wireless" type="primary" @click="handleWifi(row)">
|
||||
无线模式
|
||||
</el-button>
|
||||
<el-button type="default" @click="handleScreenUp(row)">
|
||||
点亮屏幕
|
||||
</el-button>
|
||||
@ -83,14 +86,19 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<PairDialog ref="pairDialog" @success="onPairSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isIPWithPort, sleep } from '@renderer/utils/index.js'
|
||||
import storage from '@renderer/utils/storages'
|
||||
import PairDialog from './PairDialog/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PairDialog,
|
||||
},
|
||||
data() {
|
||||
const adbCache = storage.get('adbCache') || {}
|
||||
return {
|
||||
@ -106,55 +114,80 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.getDeviceData()
|
||||
this.$adb.watch(async (type, ret) => {
|
||||
console.log('adb.watch.ret', ret)
|
||||
|
||||
this.$adb.watch(() => {
|
||||
this.getDeviceData()
|
||||
|
||||
if (type === 'add' && !isIPWithPort(ret.id)) {
|
||||
this.formData = {
|
||||
...this.formData,
|
||||
host: ret.$host,
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
async handleWifi(row) {
|
||||
try {
|
||||
const host = await this.$adb.getDeviceIP(row.id)
|
||||
const port = await this.$adb.tcpip(row.id, 5555)
|
||||
this.formData.host = host
|
||||
this.formData.port = port
|
||||
console.log('host:port', `${host}:${port}`)
|
||||
|
||||
this.handleConnect()
|
||||
}
|
||||
catch (error) {
|
||||
console.warn(error.message)
|
||||
}
|
||||
},
|
||||
onPairSuccess() {
|
||||
this.handleConnect()
|
||||
},
|
||||
handleScreenUp(row) {
|
||||
this.$adb.shell(row.id, 'input keyevent KEYCODE_POWER')
|
||||
this.$adb.deviceShell(row.id, 'input keyevent KEYCODE_POWER')
|
||||
},
|
||||
handleReset() {
|
||||
this.$electron.ipcRenderer.send('restart-app')
|
||||
},
|
||||
async handleConnect({ pairCode = '' } = {}) {
|
||||
async handleConnect() {
|
||||
if (!this.formData.host) {
|
||||
this.$message.warning('无线调试地址不能为空')
|
||||
return false
|
||||
}
|
||||
|
||||
this.connectLoading = true
|
||||
try {
|
||||
await this.$adb.connect(this.formData.host, this.formData.port || 5555, pairCode)
|
||||
await this.$adb.connect(this.formData.host, this.formData.port || 5555)
|
||||
this.$message.success('连接设备成功')
|
||||
storage.set('adbCache', this.formData)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
|
||||
if (error.message.includes('10060')) {
|
||||
this.handlePair()
|
||||
}
|
||||
this.handleError(error.message)
|
||||
}
|
||||
this.connectLoading = false
|
||||
},
|
||||
async handlePair() {
|
||||
async handleError(message) {
|
||||
try {
|
||||
const { value } = await this.$prompt('', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
await this.$confirm(
|
||||
`
|
||||
<div class="pb-4 text-sm text-red-500">错误详情:${message}</div>
|
||||
<div>可能有以下原因:</div>
|
||||
<div>1. IP地址或端口号错误</div>
|
||||
<div>2. 设备未与当前电脑配对成功</div>
|
||||
<div>3. 电脑网络和提供的设备网络IP不在同一个局域网中</div>
|
||||
<div>4. 其他未知错误</div>
|
||||
`,
|
||||
'连接设备失败',
|
||||
{
|
||||
dangerouslyUseHTMLString: true,
|
||||
confirmButtonText: '配对',
|
||||
cancelButtonText: '取消',
|
||||
inputType: 'number',
|
||||
inputPlaceholder: '请输入配对码',
|
||||
closeOnClickModal: false,
|
||||
})
|
||||
|
||||
await this.$adb.rawShell(
|
||||
`pair ${this.formData.host}:${this.formData.port || 5555} ${this.value}`,
|
||||
type: 'warning',
|
||||
},
|
||||
)
|
||||
|
||||
this.handleConnect({ pairCode: value })
|
||||
this.$refs.pairDialog.show({ params: { ...this.formData } })
|
||||
}
|
||||
catch (error) {
|
||||
console.warn(error.message)
|
||||
@ -177,7 +210,9 @@ export default {
|
||||
async handleMirror(row) {
|
||||
row.$loading = true
|
||||
try {
|
||||
await this.$scrcpy.shell(`--serial=${row.id} ${this.addScrcpyConfigs()}`)
|
||||
await this.$scrcpy.shell(
|
||||
`--serial=${row.id} --window-title=${row.name}-${row.id} ${this.addScrcpyConfigs()}`,
|
||||
)
|
||||
}
|
||||
catch (error) {
|
||||
this.$message.warning(error.message)
|
||||
|
@ -10,7 +10,7 @@ export function sleep(time = 1000) {
|
||||
|
||||
export function isIPWithPort(ip) {
|
||||
const regex
|
||||
= /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d):([1-9]|[1-9]\d{1,3}|[1-6][0-5][0-5][0-3][0-5])$/
|
||||
= /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d):(1\d{0,4}|[1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
|
||||
|
||||
return regex.test(ip)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user