feat: update user data path

This commit is contained in:
kangfenmao 2024-08-25 18:39:53 +08:00
parent e353d0f8ee
commit 93b32e8e21
6 changed files with 207 additions and 79 deletions

View File

@ -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:

View File

@ -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",

View File

@ -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')

77
src/main/utils/upgrade.ts Normal file
View File

@ -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<string> {
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)
}

View File

@ -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"
]
}
}

176
yarn.lock
View File

@ -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