mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
feat: Implement occupied directories handling during data copy (#7485)
* feat: Implement occupied directories handling during data copy - Added `occupiedDirs` constant to manage directories that should not be copied. - Enhanced the `copyOccupiedDirsInMainProcess` function to copy occupied directories to a new app data path in the main process. - Updated IPC and preload APIs to support passing occupied directories during the copy operation. - Modified the DataSettings component to utilize the new copy functionality with occupied directories. * fix: Improve occupied directories handling during data copy - Updated the filter logic in the `registerIpc` function to resolve directory paths correctly. - Modified the `DataSettings` component to pass the correct occupied directories format during the copy operation.
This commit is contained in:
parent
becb6543e0
commit
3640d846b9
@ -409,3 +409,5 @@ export enum FeedUrl {
|
||||
EARLY_ACCESS = 'https://github.com/CherryHQ/cherry-studio/releases/latest/download'
|
||||
}
|
||||
export const defaultTimeout = 5 * 1000 * 60
|
||||
|
||||
export const occupiedDirs = ['logs', 'Network', 'Partitions/webview/Network']
|
||||
|
||||
@ -1,5 +1,33 @@
|
||||
import { occupiedDirs } from '@shared/config/constant'
|
||||
import { app } from 'electron'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { initAppDataDir } from './utils/file'
|
||||
|
||||
app.isPackaged && initAppDataDir()
|
||||
|
||||
// 在主进程中复制 appData 中某些一直被占用的文件
|
||||
// 在renderer进程还没有启动时,主进程可以复制这些文件到新的appData中
|
||||
function copyOccupiedDirsInMainProcess() {
|
||||
const newAppDataPath = process.argv
|
||||
.slice(1)
|
||||
.find((arg) => arg.startsWith('--new-data-path='))
|
||||
?.split('--new-data-path=')[1]
|
||||
if (!newAppDataPath) {
|
||||
return
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const appDataPath = app.getPath('userData')
|
||||
occupiedDirs.forEach((dir) => {
|
||||
const dirPath = path.join(appDataPath, dir)
|
||||
const newDirPath = path.join(newAppDataPath, dir)
|
||||
if (fs.existsSync(dirPath)) {
|
||||
fs.cpSync(dirPath, newDirPath, { recursive: true })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
copyOccupiedDirsInMainProcess()
|
||||
|
||||
@ -269,9 +269,17 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
||||
})
|
||||
|
||||
// Copy user data to new location
|
||||
ipcMain.handle(IpcChannel.App_Copy, async (_, oldPath: string, newPath: string) => {
|
||||
ipcMain.handle(IpcChannel.App_Copy, async (_, oldPath: string, newPath: string, occupiedDirs: string[] = []) => {
|
||||
try {
|
||||
await fs.promises.cp(oldPath, newPath, { recursive: true })
|
||||
await fs.promises.cp(oldPath, newPath, {
|
||||
recursive: true,
|
||||
filter: (src) => {
|
||||
if (occupiedDirs.some((dir) => src.startsWith(path.resolve(dir)))) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
return { success: true }
|
||||
} catch (error: any) {
|
||||
log.error('Failed to copy user data:', error)
|
||||
|
||||
@ -32,7 +32,8 @@ const api = {
|
||||
hasWritePermission: (path: string) => ipcRenderer.invoke(IpcChannel.App_HasWritePermission, path),
|
||||
setAppDataPath: (path: string) => ipcRenderer.invoke(IpcChannel.App_SetAppDataPath, path),
|
||||
getDataPathFromArgs: () => ipcRenderer.invoke(IpcChannel.App_GetDataPathFromArgs),
|
||||
copy: (oldPath: string, newPath: string) => ipcRenderer.invoke(IpcChannel.App_Copy, oldPath, newPath),
|
||||
copy: (oldPath: string, newPath: string, occupiedDirs: string[] = []) =>
|
||||
ipcRenderer.invoke(IpcChannel.App_Copy, oldPath, newPath, occupiedDirs),
|
||||
setStopQuitApp: (stop: boolean, reason: string) => ipcRenderer.invoke(IpcChannel.App_SetStopQuitApp, stop, reason),
|
||||
flushAppData: () => ipcRenderer.invoke(IpcChannel.App_FlushAppData),
|
||||
isNotEmptyDir: (path: string) => ipcRenderer.invoke(IpcChannel.App_IsNotEmptyDir, path),
|
||||
|
||||
@ -19,6 +19,7 @@ import store, { useAppDispatch } from '@renderer/store'
|
||||
import { setSkipBackupFile as _setSkipBackupFile } from '@renderer/store/settings'
|
||||
import { AppInfo } from '@renderer/types'
|
||||
import { formatFileSize } from '@renderer/utils'
|
||||
import { occupiedDirs } from '@shared/config/constant'
|
||||
import { Button, Progress, Switch, Typography } from 'antd'
|
||||
import { FileText, FolderCog, FolderInput, Sparkle } from 'lucide-react'
|
||||
import { FC, useEffect, useState } from 'react'
|
||||
@ -500,7 +501,11 @@ const DataSettings: FC = () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
|
||||
// 开始复制过程
|
||||
const copyResult = await window.api.copy(originalPath, newPath)
|
||||
const copyResult = await window.api.copy(
|
||||
originalPath,
|
||||
newPath,
|
||||
occupiedDirs.map((dir) => originalPath + '/' + dir)
|
||||
)
|
||||
|
||||
// 停止进度更新
|
||||
if (progressInterval) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user