diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ca161d7..a72c126 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -226,6 +226,12 @@ jobs: $portableDir = 'release-assets/CC-Switch-Portable' New-Item -ItemType Directory -Force -Path $portableDir | Out-Null Copy-Item $exePath $portableDir + $portableIniPath = Join-Path $portableDir 'portable.ini' + $portableContent = @( + '# CC Switch portable build marker', + 'portable=true' + ) + $portableContent | Set-Content -Path $portableIniPath -Encoding UTF8 Compress-Archive -Path "$portableDir/*" -DestinationPath 'release-assets/CC-Switch-Windows-Portable.zip' -Force Remove-Item -Recurse -Force $portableDir Write-Host 'Windows portable zip created' diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index f028f19..6512371 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -674,7 +674,7 @@ pub async fn check_for_updates(handle: tauri::AppHandle) -> Result handle .opener() .open_url( - "https://github.com/farion1231/cc-switch/releases", + "https://github.com/farion1231/cc-switch/releases/latest", None::, ) .map_err(|e| format!("打开更新页面失败: {}", e))?; @@ -682,6 +682,17 @@ pub async fn check_for_updates(handle: tauri::AppHandle) -> Result Ok(true) } +/// 判断是否为便携版(绿色版)运行 +#[tauri::command] +pub async fn is_portable_mode() -> Result { + let exe_path = std::env::current_exe().map_err(|e| format!("获取可执行路径失败: {}", e))?; + if let Some(dir) = exe_path.parent() { + Ok(dir.join("portable.ini").is_file()) + } else { + Ok(false) + } +} + /// VS Code: 获取用户 settings.json 状态 #[tauri::command] pub async fn get_vscode_settings_status() -> Result { diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b539dfc..250a4da 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -377,6 +377,7 @@ pub fn run() { commands::get_settings, commands::save_settings, commands::check_for_updates, + commands::is_portable_mode, commands::get_vscode_settings_status, commands::read_vscode_settings, commands::write_vscode_settings, diff --git a/src/components/SettingsModal.tsx b/src/components/SettingsModal.tsx index 973e62d..1e00d84 100644 --- a/src/components/SettingsModal.tsx +++ b/src/components/SettingsModal.tsx @@ -35,6 +35,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) { const [showUpToDate, setShowUpToDate] = useState(false); const [resolvedClaudeDir, setResolvedClaudeDir] = useState(""); const [resolvedCodexDir, setResolvedCodexDir] = useState(""); + const [isPortable, setIsPortable] = useState(false); const { hasUpdate, updateInfo, updateHandle, checkUpdate, resetDismiss } = useUpdate(); @@ -43,6 +44,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) { loadConfigPath(); loadVersion(); loadResolvedDirs(); + loadPortableFlag(); }, []); const loadVersion = async () => { @@ -103,6 +105,15 @@ export default function SettingsModal({ onClose }: SettingsModalProps) { } }; + const loadPortableFlag = async () => { + try { + const portable = await window.api.isPortable(); + setIsPortable(portable); + } catch (error) { + console.error("检测便携模式失败:", error); + } + }; + const saveSettings = async () => { try { const payload: Settings = { @@ -126,6 +137,10 @@ export default function SettingsModal({ onClose }: SettingsModalProps) { const handleCheckUpdate = async () => { if (hasUpdate && updateHandle) { + if (isPortable) { + await window.api.checkForUpdates(); + return; + } // 已检测到更新:直接复用 updateHandle 下载并安装,避免重复检查 setIsDownloading(true); try { diff --git a/src/lib/tauri-api.ts b/src/lib/tauri-api.ts index 703c15c..29ca442 100644 --- a/src/lib/tauri-api.ts +++ b/src/lib/tauri-api.ts @@ -246,6 +246,16 @@ export const tauriAPI = { } }, + // 判断是否为便携模式 + isPortable: async (): Promise => { + try { + return await invoke("is_portable_mode"); + } catch (error) { + console.error("检测便携模式失败:", error); + return false; + } + }, + // 获取应用配置文件路径 getAppConfigPath: async (): Promise => { try { diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index e290423..2b1dd04 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -39,6 +39,7 @@ declare global { getSettings: () => Promise; saveSettings: (settings: Settings) => Promise; checkForUpdates: () => Promise; + isPortable: () => Promise; getAppConfigPath: () => Promise; openAppConfigFolder: () => Promise; // VS Code settings.json 能力