diff --git a/package.json b/package.json index 859ea1d9..d7e5e2c4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "cross-env RUST_BACKTRACE=1 tauri dev", "dev:diff": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev", - "build": "tauri build", + "build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build", "tauri": "tauri", "web:dev": "vite", "web:build": "tsc && vite build", @@ -43,6 +43,7 @@ "cli-color": "^2.0.4", "dayjs": "1.11.5", "foxact": "^0.2.35", + "glob": "^11.0.0", "i18next": "^23.11.5", "js-base64": "^3.7.7", "js-yaml": "^4.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c9c8604..baec87c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,6 +82,9 @@ importers: foxact: specifier: ^0.2.35 version: 0.2.35(react@18.3.1) + glob: + specifier: ^11.0.0 + version: 11.0.0 i18next: specifier: ^23.11.5 version: 23.11.5 @@ -1528,6 +1531,13 @@ packages: integrity: sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==, } + "@isaacs/cliui@8.0.2": + resolution: + { + integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, + } + engines: { node: ">=12" } + "@jridgewell/gen-mapping@0.3.5": resolution: { @@ -2443,6 +2453,20 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 + ansi-regex@5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } + + ansi-regex@6.1.0: + resolution: + { + integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==, + } + engines: { node: ">=12" } + ansi-styles@3.2.1: resolution: { @@ -2450,6 +2474,20 @@ packages: } engines: { node: ">=4" } + ansi-styles@4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } + + ansi-styles@6.2.1: + resolution: + { + integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, + } + engines: { node: ">=12" } + anymatch@3.1.3: resolution: { @@ -2512,6 +2550,12 @@ packages: integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==, } + balanced-match@1.0.2: + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } + before-after-hook@2.2.3: resolution: { @@ -2525,6 +2569,12 @@ packages: } engines: { node: ">=8" } + brace-expansion@2.0.1: + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } + braces@3.0.3: resolution: { @@ -2653,12 +2703,25 @@ packages: integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, } + color-convert@2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } + color-name@1.1.3: resolution: { integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, } + color-name@1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + combined-stream@1.0.8: resolution: { @@ -2825,12 +2888,30 @@ packages: integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==, } + eastasianwidth@0.2.0: + resolution: + { + integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, + } + electron-to-chromium@1.4.818: resolution: { integrity: sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==, } + emoji-regex@8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + + emoji-regex@9.2.2: + resolution: + { + integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, + } + end-of-stream@1.4.4: resolution: { @@ -2995,6 +3076,13 @@ packages: debug: optional: true + foreground-child@3.3.0: + resolution: + { + integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==, + } + engines: { node: ">=14" } + form-data@4.0.0: resolution: { @@ -3062,6 +3150,14 @@ packages: } engines: { node: ">= 6" } + glob@11.0.0: + resolution: + { + integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==, + } + engines: { node: 20 || >=22 } + hasBin: true + globals@11.12.0: resolution: { @@ -3218,6 +3314,13 @@ packages: } engines: { node: ">=0.10.0" } + is-fullwidth-code-point@3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } + is-glob@4.0.3: resolution: { @@ -3271,6 +3374,13 @@ packages: integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, } + jackspeak@4.0.2: + resolution: + { + integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==, + } + engines: { node: 20 || >=22 } + js-base64@3.7.7: resolution: { @@ -3381,6 +3491,13 @@ packages: integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==, } + lru-cache@11.0.1: + resolution: + { + integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==, + } + engines: { node: 20 || >=22 } + lru-cache@5.1.1: resolution: { @@ -3627,6 +3744,13 @@ packages: } engines: { node: ">=6" } + minimatch@10.0.1: + resolution: + { + integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==, + } + engines: { node: 20 || >=22 } + minipass@3.3.6: resolution: { @@ -3641,6 +3765,13 @@ packages: } engines: { node: ">=8" } + minipass@7.1.2: + resolution: + { + integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==, + } + engines: { node: ">=16 || 14 >=14.17" } + minizlib@2.1.2: resolution: { @@ -3824,6 +3955,12 @@ packages: } engines: { node: ">=6" } + package-json-from-dist@1.0.1: + resolution: + { + integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, + } + parent-module@1.0.1: resolution: { @@ -3870,6 +4007,13 @@ packages: integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, } + path-scurry@2.0.0: + resolution: + { + integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==, + } + engines: { node: 20 || >=22 } + path-type@4.0.0: resolution: { @@ -4239,6 +4383,13 @@ packages: integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, } + signal-exit@4.1.0: + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: ">=14" } + snake-case@3.0.4: resolution: { @@ -4291,12 +4442,40 @@ packages: integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, } + string-width@4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } + + string-width@5.1.2: + resolution: + { + integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, + } + engines: { node: ">=12" } + stringify-entities@4.0.4: resolution: { integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==, } + strip-ansi@6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } + + strip-ansi@7.1.0: + resolution: + { + integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==, + } + engines: { node: ">=12" } + strip-final-newline@2.0.0: resolution: { @@ -4667,6 +4846,20 @@ packages: engines: { node: ">= 8" } hasBin: true + wrap-ansi@7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } + + wrap-ansi@8.1.0: + resolution: + { + integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, + } + engines: { node: ">=12" } + wrappy@1.0.2: resolution: { @@ -5700,6 +5893,15 @@ snapshots: "@floating-ui/utils@0.2.4": {} + "@isaacs/cliui@8.0.2": + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + "@jridgewell/gen-mapping@0.3.5": dependencies: "@jridgewell/set-array": 1.2.1 @@ -6299,10 +6501,20 @@ snapshots: screenfull: 5.2.0 tslib: 2.6.3 + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -6352,10 +6564,16 @@ snapshots: bail@2.0.2: {} + balanced-match@1.0.2: {} + before-after-hook@2.2.3: {} binary-extensions@2.3.0: {} + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -6426,8 +6644,14 @@ snapshots: dependencies: color-name: 1.1.3 + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + color-name@1.1.3: {} + color-name@1.1.4: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -6514,8 +6738,14 @@ snapshots: no-case: 3.0.4 tslib: 2.6.3 + eastasianwidth@0.2.0: {} + electron-to-chromium@1.4.818: {} + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -6637,6 +6867,11 @@ snapshots: follow-redirects@1.15.6: {} + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -6673,6 +6908,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@11.0.0: + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.2 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + globals@11.12.0: {} has-flag@3.0.0: {} @@ -6764,6 +7008,8 @@ snapshots: is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -6782,6 +7028,10 @@ snapshots: isexe@2.0.0: {} + jackspeak@4.0.2: + dependencies: + "@isaacs/cliui": 8.0.2 + js-base64@3.7.7: {} js-cookie@2.2.1: {} @@ -6824,6 +7074,8 @@ snapshots: dependencies: tslib: 2.6.3 + lru-cache@11.0.1: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -7087,12 +7339,18 @@ snapshots: mimic-fn@2.1.0: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minipass@3.3.6: dependencies: yallist: 4.0.0 minipass@5.0.0: {} + minipass@7.1.2: {} + minizlib@2.1.2: dependencies: minipass: 3.3.6 @@ -7189,6 +7447,8 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -7219,6 +7479,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.1 + minipass: 7.1.2 + path-type@4.0.0: {} peggy@4.0.3: @@ -7461,6 +7726,8 @@ snapshots: signal-exit@3.0.7: {} + signal-exit@4.1.0: {} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -7483,11 +7750,31 @@ snapshots: space-separated-tokens@2.0.2: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-final-newline@2.0.0: {} style-to-object@1.0.6: @@ -7688,6 +7975,18 @@ snapshots: dependencies: isexe: 2.0.0 + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} yallist@3.1.1: {} diff --git a/scripts/check.mjs b/scripts/check.mjs index 0d0a3bdf..bf75cbac 100644 --- a/scripts/check.mjs +++ b/scripts/check.mjs @@ -8,6 +8,7 @@ import fetch from "node-fetch"; import proxyAgent from "https-proxy-agent"; import { execSync } from "child_process"; import { log_info, log_debug, log_error, log_success } from "./utils.mjs"; +import { glob } from "glob"; const cwd = process.cwd(); const TEMP_DIR = path.join(cwd, "node_modules/.verge"); @@ -357,16 +358,19 @@ const resolvePlugin = async () => { // service chmod const resolveServicePermission = async () => { const serviceExecutables = [ - "clash-verge-service", - "install-service", - "uninstall-service", + "clash-verge-service*", + "install-service*", + "uninstall-service*", ]; const resDir = path.join(cwd, "src-tauri/resources"); for (let f of serviceExecutables) { - const targetPath = path.join(resDir, f); - if (fs.existsSync(targetPath)) { - execSync(`chmod 755 ${targetPath}`); - log_success(`chmod finished: "${f}"`); + // 使用glob模块来处理通配符 + const files = glob.sync(path.join(resDir, f)); + for (let filePath of files) { + if (fs.existsSync(filePath)) { + execSync(`chmod 755 ${filePath}`); + log_success(`chmod finished: "${filePath}"`); + } } } }; @@ -374,29 +378,32 @@ const resolveServicePermission = async () => { /** * main */ - const SERVICE_URL = `https://github.com/clash-verge-rev/clash-verge-service/releases/download/${SIDECAR_HOST}`; const resolveService = () => { let ext = platform === "win32" ? ".exe" : ""; + let suffix = platform === "linux" ? "-" + SIDECAR_HOST : ""; resolveResource({ - file: "clash-verge-service" + ext, + file: "clash-verge-service" + suffix + ext, downloadURL: `${SERVICE_URL}/clash-verge-service${ext}`, }); }; const resolveInstall = () => { let ext = platform === "win32" ? ".exe" : ""; + let suffix = platform === "linux" ? "-" + SIDECAR_HOST : ""; resolveResource({ - file: "install-service" + ext, + file: "install-service" + suffix + ext, downloadURL: `${SERVICE_URL}/install-service${ext}`, }); }; const resolveUninstall = () => { let ext = platform === "win32" ? ".exe" : ""; + let suffix = platform === "linux" ? "-" + SIDECAR_HOST : ""; + resolveResource({ - file: "uninstall-service" + ext, + file: "uninstall-service" + suffix + ext, downloadURL: `${SERVICE_URL}/uninstall-service${ext}`, }); }; diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 1013d3a5..ea02df95 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -83,7 +83,7 @@ impl CoreManager { // 服务模式 if service::check_service().await.is_ok() { - log::debug!(target: "app", "stop the core by service"); + log::info!(target: "app", "stop the core by service"); service::stop_core_by_service().await?; } *running = false; @@ -94,7 +94,7 @@ impl CoreManager { pub async fn start_core(&self) -> Result<()> { let mut running = self.running.lock().await; if *running { - log::debug!("core is running"); + log::info!("core is running"); return Ok(()); } @@ -102,7 +102,7 @@ impl CoreManager { // 服务模式 if service::check_service().await.is_ok() { - log::debug!(target: "app", "try to run core in service mode"); + log::info!(target: "app", "try to run core in service mode"); service::run_core_by_service(&config_path).await?; *running = true; } @@ -126,7 +126,7 @@ impl CoreManager { bail!("invalid clash core name \"{clash_core}\""); } - log::debug!(target: "app", "change core to `{clash_core}`"); + log::info!(target: "app", "change core to `{clash_core}`"); Config::verge().draft().clash_core = Some(clash_core); diff --git a/src-tauri/src/core/hotkey.rs b/src-tauri/src/core/hotkey.rs index 3d685c63..a51af840 100755 --- a/src-tauri/src/core/hotkey.rs +++ b/src-tauri/src/core/hotkey.rs @@ -161,7 +161,7 @@ impl Drop for Hotkey { fn drop(&mut self) { let app_handle = handle::Handle::global().app_handle().unwrap(); if let Err(e) = app_handle.global_shortcut().unregister_all() { - log::error!("Error unregistering all hotkeys: {:?}", e); + log::error!(target:"app", "Error unregistering all hotkeys: {:?}", e); } } } diff --git a/src-tauri/src/core/service.rs b/src-tauri/src/core/service.rs index f414f8ef..f20d665b 100644 --- a/src-tauri/src/core/service.rs +++ b/src-tauri/src/core/service.rs @@ -28,6 +28,8 @@ pub struct JsonResponse { #[cfg(target_os = "windows")] pub async fn reinstall_service() -> Result<()> { + log::info!(target:"app", "reinstall service"); + use deelevate::{PrivilegeLevel, Token}; use runas::Command as RunasCommand; use std::os::windows::process::CommandExt; @@ -37,11 +39,11 @@ pub async fn reinstall_service() -> Result<()> { let uninstall_path = binary_path.with_file_name("uninstall-service.exe"); if !install_path.exists() { - bail!("installer exe not found"); + bail!(format!("installer not found: {install_path:?}")); } if !uninstall_path.exists() { - bail!("uninstaller exe not found"); + bail!(format!("uninstaller not found: {uninstall_path:?}")); } let token = Token::with_current_process()?; @@ -72,35 +74,39 @@ pub async fn reinstall_service() -> Result<()> { #[cfg(target_os = "linux")] pub async fn reinstall_service() -> Result<()> { + log::info!(target:"app", "reinstall service"); use users::get_effective_uid; - let binary_path = dirs::service_path()?; - let install_path = binary_path.with_file_name("install-service"); - let uninstall_path = binary_path.with_file_name("uninstall-service"); + let install_path = tauri::utils::platform::current_exe()?.with_file_name("install-service"); + + let uninstall_path = tauri::utils::platform::current_exe()?.with_file_name("uninstall-service"); if !install_path.exists() { - bail!("installer not found"); + bail!(format!("installer not found: {install_path:?}")); } if !uninstall_path.exists() { - bail!("uninstaller not found"); + bail!(format!("uninstaller not found: {uninstall_path:?}")); } let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ "); let uninstall_shell: String = uninstall_path.to_string_lossy().replace(" ", "\\ "); - let _ = match get_effective_uid() { - 0 => StdCommand::new(uninstall_path).status()?, - _ => StdCommand::new("sudo") + let elevator = crate::utils::help::linux_elevator(); + let status = match get_effective_uid() { + 0 => StdCommand::new(uninstall_shell).status()?, + _ => StdCommand::new(elevator) .arg("sh") .arg("-c") .arg(uninstall_shell) .status()?, }; + log::info!(target:"app", "status code:{}", status.code().unwrap()); + let elevator = crate::utils::help::linux_elevator(); let status = match get_effective_uid() { 0 => StdCommand::new(install_shell).status()?, - _ => StdCommand::new("sudo") + _ => StdCommand::new(elevator) .arg("sh") .arg("-c") .arg(install_shell) @@ -119,16 +125,18 @@ pub async fn reinstall_service() -> Result<()> { #[cfg(target_os = "macos")] pub async fn reinstall_service() -> Result<()> { + log::info!(target:"app", "reinstall service"); + let binary_path = dirs::service_path()?; let install_path = binary_path.with_file_name("install-service"); let uninstall_path = binary_path.with_file_name("uninstall-service"); if !install_path.exists() { - bail!("installer not found"); + bail!(format!("installer not found: {install_path:?}")); } if !uninstall_path.exists() { - bail!("uninstaller not found"); + bail!(format!("uninstaller not found: {uninstall_path:?}")); } let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ "); @@ -193,6 +201,8 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> { map.insert("config_file", config_file); map.insert("log_file", log_path); + log::info!(target:"app", "start service: {:?}", map.clone()); + let url = format!("{SERVICE_URL}/start_clash"); let _ = reqwest::ClientBuilder::new() .no_proxy() diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index cbf8245a..c123b676 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -58,6 +58,7 @@ pub fn run() { } tauri::async_runtime::block_on(async move { resolve::resolve_setup(app).await; + #[cfg(not(target_os = "macos"))] { let argvs: Vec = std::env::args().collect(); diff --git a/src-tauri/src/utils/dirs.rs b/src-tauri/src/utils/dirs.rs index e4030620..842b27fe 100644 --- a/src-tauri/src/utils/dirs.rs +++ b/src-tauri/src/utils/dirs.rs @@ -47,11 +47,9 @@ pub fn app_home_dir() -> Result { let app_handle = handle::Handle::global().app_handle().unwrap(); match app_handle.path().data_dir() { - Ok(dir) => { - Ok(dir.join(APP_ID)) - } + Ok(dir) => Ok(dir.join(APP_ID)), Err(e) => { - log::error!("Failed to get the app home directory: {}", e); + log::error!(target:"app", "Failed to get the app home directory: {}", e); Err(anyhow::anyhow!("Failed to get the app homedirectory")) } } @@ -61,11 +59,9 @@ pub fn app_home_dir() -> Result { pub fn app_resources_dir() -> Result { let app_handle = handle::Handle::global().app_handle().unwrap(); match app_handle.path().resource_dir() { - Ok(dir) => { - Ok(dir.join("resources")) - } + Ok(dir) => Ok(dir.join("resources")), Err(e) => { - log::error!("Failed to get the resource directory: {}", e); + log::error!(target:"app", "Failed to get the resource directory: {}", e); Err(anyhow::anyhow!("Failed to get the resource directory")) } } diff --git a/src-tauri/src/utils/help.rs b/src-tauri/src/utils/help.rs index 3583540a..b6fda2a9 100644 --- a/src-tauri/src/utils/help.rs +++ b/src-tauri/src/utils/help.rs @@ -105,6 +105,26 @@ pub fn open_file(app: tauri::AppHandle, path: PathBuf) -> Result<()> { Ok(()) } +#[cfg(target_os = "linux")] +pub fn linux_elevator() -> String { + use std::process::Command; + match Command::new("which").arg("sudo").output() { + Ok(output) => { + if !output.stdout.is_empty() { + // Convert the output to a string slice + if let Ok(path) = std::str::from_utf8(&output.stdout) { + path.trim().to_string() + } else { + "sudo".to_string() + } + } else { + "sudo".to_string() + } + } + Err(_) => "sudo".to_string(), + } +} + #[macro_export] macro_rules! error { ($result: expr) => { diff --git a/src-tauri/src/utils/init.rs b/src-tauri/src/utils/init.rs index 5c0b9c60..609012af 100644 --- a/src-tauri/src/utils/init.rs +++ b/src-tauri/src/utils/init.rs @@ -195,8 +195,10 @@ pub fn init_resources() -> Result<()> { #[cfg(target_os = "windows")] let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"]; - #[cfg(not(target_os = "windows"))] + #[cfg(target_os = "macos")] let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"]; + #[cfg(target_os = "linux")] + let file_list: [&str; 0] = []; // copy the resource file // if the source file is newer than the destination file, copy it over @@ -204,12 +206,13 @@ pub fn init_resources() -> Result<()> { let src_path = res_dir.join(file); let dest_path = app_dir.join(file); let test_dest_path = test_dir.join(file); + log::info!(target: "app", "src_path: {src_path:?}, dest_path: {dest_path:?}"); let handle_copy = |dest: &PathBuf| { match fs::copy(&src_path, dest) { Ok(_) => log::debug!(target: "app", "resources copied '{file}'"), Err(err) => { - log::error!(target: "app", "failed to copy resources '{file}', {err}") + log::error!(target: "app", "failed to copy resources '{file}' to '{dest:?}', {err}") } }; }; diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index 074aea4a..28b6adc9 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/src-tauri/src/utils/resolve.rs @@ -43,12 +43,6 @@ pub async fn resolve_setup(app: &mut App) { handle::Handle::global().init(app.app_handle()); VERSION.get_or_init(|| version.clone()); - if service::check_service().await.is_err() { - log_err!(service::reinstall_service().await); - //延迟启动,避免闪屏 - std::thread::sleep(std::time::Duration::from_millis(1000)); - } - log_err!(init::init_config()); log_err!(init::init_resources()); log_err!(init::init_scheme()); @@ -56,18 +50,22 @@ pub async fn resolve_setup(app: &mut App) { // 处理随机端口 log_err!(resolve_random_port_config()); // 启动核心 - log::trace!("init config"); - + log::trace!(target:"app", "init config"); log_err!(Config::init_config().await); - log::trace!("launch core"); + if service::check_service().await.is_err() { + log_err!(service::reinstall_service().await); + std::thread::sleep(std::time::Duration::from_millis(1000)); + } + + log::trace!(target: "app", "launch core"); log_err!(CoreManager::global().init().await); // setup a simple http server for singleton - log::trace!("launch embed server"); + log::trace!(target: "app", "launch embed server"); server::embed_server(); - log::trace!("init system tray"); + log::trace!(target: "app", "init system tray"); log_err!(tray::Tray::create_systray()); let silent_start = { Config::verge().data().enable_silent_start }; @@ -160,7 +158,7 @@ pub fn create_window() { .latest() .window_is_maximized .unwrap_or(false); - log::trace!("try to calculate the monitor size"); + log::trace!(target:"app", "try to calculate the monitor size"); let center = (|| -> Result { let mut center = false; let monitor = win.current_monitor()?.ok_or(anyhow::anyhow!(""))?; @@ -220,7 +218,7 @@ pub fn save_window_size_position(save_to_file: bool) -> Result<()> { } pub async fn resolve_scheme(param: String) -> Result<()> { - log::info!("received deep link: {}", param); + log::info!(target:"app", "received deep link: {}", param); let app_handle = handle::Handle::global().app_handle().unwrap(); diff --git a/src-tauri/tauri.linux.conf.json b/src-tauri/tauri.linux.conf.json index 774ba634..7493b270 100644 --- a/src-tauri/tauri.linux.conf.json +++ b/src-tauri/tauri.linux.conf.json @@ -18,7 +18,14 @@ "conflicts": ["clash-verge"], "obsoletes": ["clash-verge"] } - } + }, + "externalBin": [ + "./resources/clash-verge-service", + "./resources/install-service", + "./resources/uninstall-service", + "./sidecar/verge-mihomo", + "./sidecar/verge-mihomo-alpha" + ] }, "app": { "trayIcon": {