From 7a19e09b1d9528610238c703aee5e6640a20f2fc Mon Sep 17 00:00:00 2001 From: yinxue <2643126914@qq.com> Date: Thu, 8 Jan 2026 08:40:12 +0000 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E7=94=A8=E6=96=B0=E5=BC=80=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E7=BB=88=E7=AB=AF=E7=9A=84=E6=96=B9=E5=BC=8F=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=B3=BB=E7=BB=9F=E5=92=8C=E7=BB=88=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 +++ src/remote-container.ts | 62 ++++++++++++++++++++++++-------------- src/utils.ts | 67 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 865a752..1b52c91 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,10 @@ { "protocol": "vscode", "path": "/openProject" + }, + { + "protocol": "trae", + "path": "/openProject" } ], "views": { diff --git a/src/remote-container.ts b/src/remote-container.ts index 5228449..9aa8e23 100644 --- a/src/remote-container.ts +++ b/src/remote-container.ts @@ -25,6 +25,43 @@ export default class RemoteContainer { this.user = user; } + /** + * 构建打开项目的命令 + * 在远程环境下,通过本地终端实时检测本地系统类型和 PowerShell 版本 + * 支持 Windows/Linux/Mac 作为本地系统的所有场景 + */ + private async buildOpenProjectCommand( + host: string, + hostname: string, + port: number, + username: string, + path: string, + devstarDomain?: string + ): Promise { + const baseUrl = `vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}`; + const url = devstarDomain ? `${baseUrl}&devstar_domain=${devstarDomain}` : baseUrl; + + // 检测本地系统类型和 PowerShell 版本 + try { + const localSystemInfo = await utils.detectLocalSystemInfo(); + console.log('本地系统检测结果:', localSystemInfo); + + // 只有本地是 Windows 系统才使用 PowerShell 语法 + if (localSystemInfo.isWindows) { + // PowerShell 需要使用单引号包裹 URL,内部协议用双引号 + // 格式:code --new-window; code --open-url '"vscode://..."' + console.log('使用 PowerShell 语法(单引号嵌套双引号)'); + return `code --new-window; code --open-url '"${url}"'`; + } + } catch (error) { + console.log('检测本地系统失败,使用默认命令格式:', error); + } + + // 默认使用 && 语法(适用于 Linux/macOS) + console.log('使用默认命令语法 (&&)'); + return `code --new-window && code --open-url "${url}"`; + } + /** * 第一次打开远程项目 */ @@ -40,29 +77,8 @@ export default class RemoteContainer { devstarDomain = undefined; } - const semver = require('semver'); - const powershellVersion = context.globalState.get('powershellVersion'); - const powershell_semver_compatible_version = semver.coerce(powershellVersion); - - let command = ''; - if (devstarDomain === undefined) { - if (powershellVersion === undefined) { - command = `code --new-window && code --open-url "vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}"`; - } else if (semver.satisfies(powershell_semver_compatible_version, ">=5.1.26100")) { - command = `code --new-window ; code --% --open-url "vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}"`; - } else { - command = `code --new-window && code --open-url "vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}"`; - } - } else { - if (powershellVersion === undefined) { - command = `code --new-window && code --open-url "vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}&devstar_domain=${devstarDomain}"`; - } else if (semver.satisfies(powershell_semver_compatible_version, ">=5.1.26100")) { - command = `code --new-window ; code --% --open-url "vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}&devstar_domain=${devstarDomain}"`; - } else { - command = `code --new-window && code --open-url "vscode://mengning.devstar/openProjectSkippingLoginCheck?host=${host}&hostname=${hostname}&port=${port}&username=${username}&path=${path}&devstar_domain=${devstarDomain}"`; - } - } - + // 在本地终端实时检测命令格式 + const command = await this.buildOpenProjectCommand(host, hostname, port, username, path, devstarDomain); terminal.sendText(command); } else { vscode.window.showErrorMessage('无法创建终端,请检查终端是否可用。'); diff --git a/src/utils.ts b/src/utils.ts index 9315a37..e852352 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -131,4 +131,71 @@ export async function powershellVersion(): Promise { resolve(stdout.trim()); }); }); +} + +/** + * 在远程环境下,通过执行本地命令来检测本地系统信息 + * 不依赖 os.platform(),因为在远程环境下它返回的是远程系统类型 + */ +export async function detectLocalSystemInfo(): Promise<{ + isWindows: boolean; + isLinux: boolean; + isMac: boolean; + powershellVersion?: string; +}> { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + reject(new Error('系统检测超时')); + }, 3000); + + // 尝试执行 PowerShell 命令来检测是否为 Windows + exec('powershell -Command "$PSVersionTable.PSVersion.ToString()"', (error, stdout, stderr) => { + clearTimeout(timeout); + + if (!error && stdout && !stderr) { + // PowerShell 命令成功执行,说明是 Windows 系统 + resolve({ + isWindows: true, + isLinux: false, + isMac: false, + powershellVersion: stdout.trim() + }); + } else { + // PowerShell 命令失败,尝试检测 Unix 系统类型 + exec('uname -s', (unameError, unameStdout) => { + if (!unameError && unameStdout) { + const osType = unameStdout.trim(); + resolve({ + isWindows: false, + isLinux: osType === 'Linux', + isMac: osType === 'Darwin', + powershellVersion: undefined + }); + } else { + // 无法检测,返回默认值 + resolve({ + isWindows: false, + isLinux: false, + isMac: false, + powershellVersion: undefined + }); + } + }); + } + }); + }); +} + +/** + * 在远程环境下,通过本地终端实时检测 PowerShell 版本 + * 这样可以确保获取到最准确的版本信息,而不依赖于 globalState + * @deprecated 使用 detectLocalSystemInfo 替代 + */ +export async function detectLocalPowershellVersion(): Promise { + try { + const systemInfo = await detectLocalSystemInfo(); + return systemInfo.powershellVersion || ''; + } catch (error) { + return ''; + } } \ No newline at end of file