Procházet zdrojové kódy

解决安装Git时的报错

黄中银 před 3 týdny
rodič
revize
c133a4e1e3

+ 3 - 1
ApqInstaller/electron/modules/installer.ts

@@ -1009,5 +1009,7 @@ export {
   getNodeInstallArgs,
   getVSCodeInstallArgs,
   getGitInstallArgs,
-  aptUpdate
+  aptUpdate,
+  getNpmPath,
+  getPnpmPath
 }

+ 48 - 11
ApqInstaller/electron/modules/ipc-handlers.ts

@@ -18,7 +18,8 @@ import {
   installVscode,
   installGit,
   installAll,
-  uninstallSoftware
+  uninstallSoftware,
+  getNpmPath
 } from './installer'
 import { addInstallHistory, getInstallHistory } from './config'
 import logger from './logger'
@@ -314,21 +315,57 @@ export function registerHandlers(): void {
       logger.info('开始安装 Claude Code...')
       sendToRenderer('install-status', { software: 'claudeCode', message: '正在安装 Claude Code...', progress: 30 })
 
-      // 使用 npm 全局安装 @anthropic-ai/claude-code
-      await execa('npm', ['install', '-g', '@anthropic-ai/claude-code'])
+      // 使用完整的 npm 路径,避免 PATH 未生效的问题
+      const npmPath = getNpmPath()
+      logger.info(`使用 npm 路径: ${npmPath}`)
 
-      sendToRenderer('install-status', { software: 'claudeCode', message: '安装完成,正在验证...', progress: 90 })
+      // 使用 npm 全局安装 @anthropic-ai/claude-code
+      const result = await execa(npmPath, ['install', '-g', '@anthropic-ai/claude-code'], {
+        encoding: 'utf8',
+        // 捕获输出以便记录日志
+        stdout: 'pipe',
+        stderr: 'pipe'
+      })
 
-      // 验证安装
-      const result = await execa('claude', ['--version'])
-      const version = result.stdout.trim()
+      // 记录安装输出
+      if (result.stdout) {
+        logger.info(`npm install stdout: ${result.stdout}`)
+      }
+      if (result.stderr) {
+        logger.warn(`npm install stderr: ${result.stderr}`)
+      }
 
-      logger.info(`Claude Code 安装成功: ${version}`)
-      sendToRenderer('install-complete', { software: 'claudeCode', message: '✅ Claude Code 安装完成!' })
+      sendToRenderer('install-status', { software: 'claudeCode', message: '安装完成,正在验证...', progress: 90 })
 
-      return { success: true }
+      // 验证安装 - 使用 commandExistsWithRefresh 来刷新 PATH
+      const { commandExistsWithRefresh, getCommandVersionWithRefresh } = await import('./utils')
+      const claudeExists = await commandExistsWithRefresh('claude')
+
+      if (claudeExists) {
+        const version = await getCommandVersionWithRefresh('claude', ['--version'])
+        logger.info(`Claude Code 安装成功: ${version}`)
+        sendToRenderer('install-complete', { software: 'claudeCode', message: '✅ Claude Code 安装完成!' })
+        return { success: true }
+      } else {
+        // 即使验证失败,安装可能已成功,只是 PATH 还没生效
+        logger.info('Claude Code 安装完成,但验证失败(可能需要重启终端)')
+        sendToRenderer('install-complete', { software: 'claudeCode', message: '✅ Claude Code 安装完成!(可能需要重启终端才能使用)' })
+        return { success: true }
+      }
     } catch (error) {
-      const errorMessage = (error as Error).message
+      // 提取更有意义的错误信息
+      const execaError = error as { message?: string; stderr?: string; stdout?: string; shortMessage?: string }
+      let errorMessage = execaError.shortMessage || execaError.message || '未知错误'
+
+      // 如果有 stderr,尝试从中提取有用信息
+      if (execaError.stderr) {
+        // 过滤掉乱码字符,只保留可读字符
+        const stderrClean = execaError.stderr.replace(/[^\x20-\x7E\u4e00-\u9fa5\n\r]/g, '').trim()
+        if (stderrClean) {
+          errorMessage = `${errorMessage}\n${stderrClean}`
+        }
+      }
+
       logger.error('Claude Code 安装失败', error)
       sendToRenderer('install-error', { software: 'claudeCode', message: `❌ 安装失败:${errorMessage}` })
       return { success: false, error: errorMessage }