diff --git a/server.js b/server.js index 5197fbb..a8235b7 100755 --- a/server.js +++ b/server.js @@ -439,19 +439,21 @@ function trashPath(p) { try { target = resolvePath(p); } catch { return resolve({ ok: false, error: '非法路径' }); } let isDir = false; try { isDir = fs.lstatSync(target).isDirectory(); } catch { return resolve({ ok: false, error: '文件不存在' }); } - let cmd; + let bin, args; if (PLATFORM === 'darwin') { // 路径走 argv,不拼进单引号 AppleScript 字面量——避免含 ' 的文件名删除失败/注入 // POSIX file 必须 as alias 强转,否则 Finder 解析不了报 -1728 - cmd = `osascript -e 'on run argv' -e 'tell application "Finder" to delete (POSIX file (item 1 of argv) as alias)' -e 'end run' ${shellQuote(target)}`; + bin = 'osascript'; + args = ['-e', 'on run argv', '-e', 'tell application "Finder" to delete (POSIX file (item 1 of argv) as alias)', '-e', 'end run', target]; } else if (PLATFORM === 'win32') { const method = isDir ? 'DeleteDirectory' : 'DeleteFile'; - const ps = target.replace(/'/g, "''"); - cmd = `powershell -NoProfile -Command "Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.FileIO.FileSystem]::${method}('${ps}','OnlyErrorDialogs','SendToRecycleBin')"`; + bin = 'powershell'; + args = ['-NoProfile', '-Command', `Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.FileIO.FileSystem]::${method}('${target.replace(/'/g, "''")}','OnlyErrorDialogs','SendToRecycleBin')`]; } else { - cmd = `gio trash ${shellQuote(target)} || trash-put ${shellQuote(target)} || trash ${shellQuote(target)}`; + bin = 'sh'; + args = ['-c', 'gio trash "$1" || trash-put "$1" || trash "$1"', '--', target]; } - exec(cmd, (err) => { + execFile(bin, args, (err) => { if (!err) return resolve({ ok: true }); let msg = err.message; // Finder 自动化未授权(-1743/-600)给人话 @@ -1239,10 +1241,11 @@ function openInOS(target, withApp) { if (withApp === 'terminal') { // 在该目录(文件则取其所在目录)打开系统终端,找回项目后一键去跑 const dir = (() => { try { return fs.statSync(target).isDirectory() ? target : path.dirname(target); } catch { return path.dirname(target); } })(); - if (PLATFORM === 'darwin') cmd = `open -a Terminal ${shellQuote(dir)}`; - else if (PLATFORM === 'win32') cmd = `start "" cmd /K cd /d "${dir}"`; - else cmd = `x-terminal-emulator --working-directory=${shellQuote(dir)} || gnome-terminal --working-directory=${shellQuote(dir)} || xterm`; - exec(cmd, (err) => resolve(err ? { ok: false, error: err.message } : { ok: true, with: 'terminal' })); + let tBin, tArgs; + if (PLATFORM === 'darwin') { tBin = 'open'; tArgs = ['-a', 'Terminal', dir]; } + else if (PLATFORM === 'win32') { tBin = 'cmd.exe'; tArgs = ['/c', 'start', '', 'cmd', '/K', 'cd', '/d', dir]; } + else { tBin = 'sh'; tArgs = ['-c', 'x-terminal-emulator --working-directory="$1" || gnome-terminal --working-directory="$1" || xterm', '--', dir]; } + execFile(tBin, tArgs, (err) => resolve(err ? { ok: false, error: err.message } : { ok: true, with: 'terminal' })); return; } if (withApp === 'editor') { @@ -1263,18 +1266,18 @@ function openInOS(target, withApp) { function openDefault(target, withApp) { return new Promise((resolve) => { - let cmd; + let bin, args; if (PLATFORM === 'darwin') { - if (withApp === 'reveal') cmd = `open -R ${shellQuote(target)}`; - else cmd = `open ${shellQuote(target)}`; + if (withApp === 'reveal') { bin = 'open'; args = ['-R', target]; } + else { bin = 'open'; args = [target]; } } else if (PLATFORM === 'win32') { - if (withApp === 'reveal') cmd = `explorer /select,"${target}"`; - else cmd = `start "" "${target}"`; + if (withApp === 'reveal') { bin = 'explorer.exe'; args = ['/select,' + target]; } + else { bin = 'cmd.exe'; args = ['/c', 'start', '', target]; } } else { - if (withApp === 'reveal') cmd = `xdg-open ${shellQuote(path.dirname(target))}`; - else cmd = `xdg-open ${shellQuote(target)}`; + if (withApp === 'reveal') { bin = 'xdg-open'; args = [path.dirname(target)]; } + else { bin = 'xdg-open'; args = [target]; } } - exec(cmd, (err) => { + execFile(bin, args, (err) => { if (err) resolve({ ok: false, error: err.message }); else resolve({ ok: true, with: withApp || 'default' }); });