From 93b32e8e21fb659772e88c59bb435b62ff25f856 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Sun, 25 Aug 2024 18:39:53 +0800 Subject: [PATCH] feat: update user data path --- electron-builder.yml | 9 ++ package.json | 8 +- src/main/index.ts | 5 +- src/main/utils/upgrade.ts | 77 +++++++++++++++++ tsconfig.node.json | 11 ++- yarn.lock | 176 ++++++++++++++++++++++---------------- 6 files changed, 207 insertions(+), 79 deletions(-) create mode 100644 src/main/utils/upgrade.ts diff --git a/electron-builder.yml b/electron-builder.yml index 01e7808bf..47d75023d 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -11,6 +11,15 @@ files: - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' asarUnpack: - resources/** +extraResources: + - from: './ollama/bin' + to: 'ollama/bin' + filter: + - 'ollama-${os}.zip' + - from: './ollama/models' + to: 'ollama/models' + filter: + - '**/*' win: executableName: Cherry Studio nsis: diff --git a/package.json b/package.json index e4c314118..7af4e1d41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { - "name": "cherry-studio", + "name": "CherryStudio", "version": "0.6.1", + "private": true, "description": "A powerful AI assistant for producer.", "main": "./out/main/index.js", "author": "kangfenmao@qq.com", @@ -26,6 +27,8 @@ "@electron-toolkit/preload": "^3.0.0", "@electron-toolkit/utils": "^3.0.0", "@sentry/electron": "^5.2.0", + "adm-zip": "^0.5.15", + "electron-devtools-installer": "^3.2.0", "electron-log": "^5.1.5", "electron-store": "^8.2.0", "electron-updater": "^6.1.7", @@ -41,6 +44,7 @@ "@hello-pangea/dnd": "^16.6.0", "@kangfenmao/keyv-storage": "^0.1.0", "@reduxjs/toolkit": "^2.2.5", + "@types/adm-zip": "^0", "@types/lodash": "^4.17.5", "@types/node": "^18.19.9", "@types/react": "^18.2.48", @@ -53,7 +57,6 @@ "dotenv-cli": "^7.4.2", "electron": "^28.2.0", "electron-builder": "^24.9.1", - "electron-devtools-installer": "^3.2.0", "electron-vite": "^2.0.0", "emittery": "^1.0.3", "emoji-picker-element": "^1.22.1", @@ -76,6 +79,7 @@ "react-router-dom": "6", "react-spinners": "^0.14.1", "react-syntax-highlighter": "^15.5.0", + "redux": "^5.0.1", "redux-persist": "^6.0.0", "rehype-katex": "^7.0.0", "remark-gfm": "^4.0.0", diff --git a/src/main/index.ts b/src/main/index.ts index daecad129..716466d82 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -4,12 +4,15 @@ import { app, BrowserWindow } from 'electron' import installExtension, { REDUX_DEVTOOLS } from 'electron-devtools-installer' import { registerIpc } from './ipc' +import { updateUserDataPath } from './utils/upgrade' import { createMainWindow } from './window' // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. -app.whenReady().then(() => { +app.whenReady().then(async () => { + await updateUserDataPath() + // Set app user model id for windows electronApp.setAppUserModelId('com.kangfenmao.CherryStudio') diff --git a/src/main/utils/upgrade.ts b/src/main/utils/upgrade.ts new file mode 100644 index 000000000..d9de5eda9 --- /dev/null +++ b/src/main/utils/upgrade.ts @@ -0,0 +1,77 @@ +import { spawn } from 'child_process' +import { app, dialog } from 'electron' +import Logger from 'electron-log' +import fs from 'fs' +import path from 'path' + +export async function updateUserDataPath() { + const currentPath = app.getPath('userData') + const oldPath = currentPath.replace('CherryStudio', 'cherry-studio') + + if (fs.existsSync(oldPath)) { + Logger.log('更新 userData 路径') + + try { + if (process.platform === 'win32') { + // Windows 系统:创建 bat 文件 + const batPath = await createWindowsBatFile(oldPath, currentPath) + await promptRestartAndExecute(batPath) + } else { + // 其他系统:直接更新 + fs.rmSync(currentPath, { recursive: true, force: true }) + fs.renameSync(oldPath, currentPath) + Logger.log(`目录已重命名: ${currentPath}`) + await promptRestart() + } + } catch (error: any) { + Logger.error('更新 userData 路径时出错:', error) + dialog.showErrorBox('错误', `更新用户数据目录时发生错误: ${error.message}`) + } + } else { + Logger.log('userData 路径不需要更新') + } +} + +async function createWindowsBatFile(oldPath: string, currentPath: string): Promise { + const batPath = path.join(app.getPath('temp'), 'rename_userdata.bat') + const appPath = app.getPath('exe') + const batContent = ` +@echo off +timeout /t 2 /nobreak +rmdir /s /q "${currentPath}" +rename "${oldPath}" "${path.basename(currentPath)}" +start "" "${appPath}" +del "%~f0" + ` + fs.writeFileSync(batPath, batContent) + return batPath +} + +async function promptRestartAndExecute(batPath: string) { + await dialog.showMessageBox({ + type: 'info', + title: '应用需要重启', + message: '用户数据目录将在重启后更新。请重启应用以应用更改。', + buttons: ['手动重启'] + }) + + // 执行 bat 文件 + spawn('cmd.exe', ['/c', batPath], { + detached: true, + stdio: 'ignore' + }) + + app.exit(0) +} + +async function promptRestart() { + await dialog.showMessageBox({ + type: 'info', + title: '应用需要重启', + message: '用户数据目录已更新。请重启应用以应用更改。', + buttons: ['重启'] + }) + + app.relaunch() + app.exit(0) +} diff --git a/tsconfig.node.json b/tsconfig.node.json index db23a68cc..52b576caa 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,8 +1,15 @@ { "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", - "include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*"], + "include": [ + "electron.vite.config.*", + "src/main/**/*", + "src/preload/**/*", + "src/main/env.d.ts" + ], "compilerOptions": { "composite": true, - "types": ["electron-vite/node"] + "types": [ + "electron-vite/node" + ] } } diff --git a/yarn.lock b/yarn.lock index 2411b0ecb..7ae53862d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1932,6 +1932,15 @@ __metadata: languageName: node linkType: hard +"@types/adm-zip@npm:^0": + version: 0.5.5 + resolution: "@types/adm-zip@npm:0.5.5" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/4976dc61e33534ecfb7eee87e8a587db06420a4eb9f34eee9425aece82e9fdd01ddd22677ff6430c582f4d9735c7d714c71adb8f149e3511bc189501b4113631 + languageName: node + linkType: hard + "@types/babel__core@npm:^7.20.5": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" @@ -2607,6 +2616,79 @@ __metadata: languageName: node linkType: hard +"CherryStudio@workspace:.": + version: 0.0.0-use.local + resolution: "CherryStudio@workspace:." + dependencies: + "@anthropic-ai/sdk": "npm:^0.24.3" + "@electron-toolkit/eslint-config-prettier": "npm:^2.0.0" + "@electron-toolkit/eslint-config-ts": "npm:^1.0.1" + "@electron-toolkit/preload": "npm:^3.0.0" + "@electron-toolkit/tsconfig": "npm:^1.0.1" + "@electron-toolkit/utils": "npm:^3.0.0" + "@google/generative-ai": "npm:^0.16.0" + "@hello-pangea/dnd": "npm:^16.6.0" + "@kangfenmao/keyv-storage": "npm:^0.1.0" + "@reduxjs/toolkit": "npm:^2.2.5" + "@sentry/electron": "npm:^5.2.0" + "@types/adm-zip": "npm:^0" + "@types/lodash": "npm:^4.17.5" + "@types/node": "npm:^18.19.9" + "@types/react": "npm:^18.2.48" + "@types/react-dom": "npm:^18.2.18" + "@vitejs/plugin-react": "npm:^4.2.1" + adm-zip: "npm:^0.5.15" + antd: "npm:^5.18.3" + axios: "npm:^1.7.3" + browser-image-compression: "npm:^2.0.2" + dayjs: "npm:^1.11.11" + dotenv-cli: "npm:^7.4.2" + electron: "npm:^28.2.0" + electron-builder: "npm:^24.9.1" + electron-devtools-installer: "npm:^3.2.0" + electron-log: "npm:^5.1.5" + electron-store: "npm:^8.2.0" + electron-updater: "npm:^6.1.7" + electron-vite: "npm:^2.0.0" + electron-window-state: "npm:^5.0.3" + emittery: "npm:^1.0.3" + emoji-picker-element: "npm:^1.22.1" + eslint: "npm:^8.56.0" + eslint-plugin-react: "npm:^7.34.3" + eslint-plugin-react-hooks: "npm:^4.6.2" + eslint-plugin-simple-import-sort: "npm:^12.1.1" + eslint-plugin-unused-imports: "npm:^4.0.0" + gpt-tokens: "npm:^1.3.6" + i18next: "npm:^23.11.5" + localforage: "npm:^1.10.0" + lodash: "npm:^4.17.21" + openai: "npm:^4.52.1" + prettier: "npm:^3.2.4" + react: "npm:^18.2.0" + react-dom: "npm:^18.2.0" + react-i18next: "npm:^14.1.2" + react-markdown: "npm:^9.0.1" + react-redux: "npm:^9.1.2" + react-router: "npm:6" + react-router-dom: "npm:6" + react-spinners: "npm:^0.14.1" + react-syntax-highlighter: "npm:^15.5.0" + redux: "npm:^5.0.1" + redux-persist: "npm:^6.0.0" + rehype-katex: "npm:^7.0.0" + remark-gfm: "npm:^4.0.0" + remark-math: "npm:^6.0.0" + sass: "npm:^1.77.2" + styled-components: "npm:^6.1.11" + typescript: "npm:^5.3.3" + uuid: "npm:^10.0.0" + vite: "npm:^5.0.12" + peerDependencies: + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + languageName: unknown + linkType: soft + "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" @@ -2668,6 +2750,13 @@ __metadata: languageName: node linkType: hard +"adm-zip@npm:^0.5.15": + version: 0.5.15 + resolution: "adm-zip@npm:0.5.15" + checksum: 10c0/40ad504176c4b7f41983d11f7ff28acd3ce5b9bd51a09356be2447cb1799de4a4d93f8b0f65f75814add17687445cc807bbcb5ec8f73f44af1aefe4509894a8c + languageName: node + linkType: hard + "agent-base@npm:6": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -3435,76 +3524,6 @@ __metadata: languageName: node linkType: hard -"cherry-studio@workspace:.": - version: 0.0.0-use.local - resolution: "cherry-studio@workspace:." - dependencies: - "@anthropic-ai/sdk": "npm:^0.24.3" - "@electron-toolkit/eslint-config-prettier": "npm:^2.0.0" - "@electron-toolkit/eslint-config-ts": "npm:^1.0.1" - "@electron-toolkit/preload": "npm:^3.0.0" - "@electron-toolkit/tsconfig": "npm:^1.0.1" - "@electron-toolkit/utils": "npm:^3.0.0" - "@google/generative-ai": "npm:^0.16.0" - "@hello-pangea/dnd": "npm:^16.6.0" - "@kangfenmao/keyv-storage": "npm:^0.1.0" - "@reduxjs/toolkit": "npm:^2.2.5" - "@sentry/electron": "npm:^5.2.0" - "@types/lodash": "npm:^4.17.5" - "@types/node": "npm:^18.19.9" - "@types/react": "npm:^18.2.48" - "@types/react-dom": "npm:^18.2.18" - "@vitejs/plugin-react": "npm:^4.2.1" - antd: "npm:^5.18.3" - axios: "npm:^1.7.3" - browser-image-compression: "npm:^2.0.2" - dayjs: "npm:^1.11.11" - dotenv-cli: "npm:^7.4.2" - electron: "npm:^28.2.0" - electron-builder: "npm:^24.9.1" - electron-devtools-installer: "npm:^3.2.0" - electron-log: "npm:^5.1.5" - electron-store: "npm:^8.2.0" - electron-updater: "npm:^6.1.7" - electron-vite: "npm:^2.0.0" - electron-window-state: "npm:^5.0.3" - emittery: "npm:^1.0.3" - emoji-picker-element: "npm:^1.22.1" - eslint: "npm:^8.56.0" - eslint-plugin-react: "npm:^7.34.3" - eslint-plugin-react-hooks: "npm:^4.6.2" - eslint-plugin-simple-import-sort: "npm:^12.1.1" - eslint-plugin-unused-imports: "npm:^4.0.0" - gpt-tokens: "npm:^1.3.6" - i18next: "npm:^23.11.5" - localforage: "npm:^1.10.0" - lodash: "npm:^4.17.21" - openai: "npm:^4.52.1" - prettier: "npm:^3.2.4" - react: "npm:^18.2.0" - react-dom: "npm:^18.2.0" - react-i18next: "npm:^14.1.2" - react-markdown: "npm:^9.0.1" - react-redux: "npm:^9.1.2" - react-router: "npm:6" - react-router-dom: "npm:6" - react-spinners: "npm:^0.14.1" - react-syntax-highlighter: "npm:^15.5.0" - redux-persist: "npm:^6.0.0" - rehype-katex: "npm:^7.0.0" - remark-gfm: "npm:^4.0.0" - remark-math: "npm:^6.0.0" - sass: "npm:^1.77.2" - styled-components: "npm:^6.1.11" - typescript: "npm:^5.3.3" - uuid: "npm:^10.0.0" - vite: "npm:^5.0.12" - peerDependencies: - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - languageName: unknown - linkType: soft - "chokidar@npm:>=3.0.0 <4.0.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" @@ -9535,7 +9554,16 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:^7.2.1": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf + languageName: node + linkType: hard + +"semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.6.2 resolution: "semver@npm:7.6.2" bin: @@ -10096,9 +10124,9 @@ __metadata: linkType: hard "tslib@npm:^2.1.0": - version: 2.6.3 - resolution: "tslib@npm:2.6.3" - checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a + version: 2.7.0 + resolution: "tslib@npm:2.7.0" + checksum: 10c0/469e1d5bf1af585742128827000711efa61010b699cb040ab1800bcd3ccdd37f63ec30642c9e07c4439c1db6e46345582614275daca3e0f4abae29b0083f04a6 languageName: node linkType: hard