🐛 Fix(custom): fix auto start on linux

ISSUES CLOSED: #394
This commit is contained in:
Kuingsmile
2025-09-25 11:49:01 +08:00
parent 5b79e43679
commit 94056a1062
6 changed files with 102 additions and 7 deletions

View File

@@ -2,11 +2,12 @@ import path from 'node:path'
import { dbPathDir } from '@core/datastore/dbChecker'
import picgo from '@core/picgo'
import { app, IpcMainEvent, shell } from 'electron'
import { IpcMainEvent, shell } from 'electron'
import fs from 'fs-extra'
import type { IIPCEvent } from '#/types/rpc'
import type { IObj } from '#/types/types'
import { isAutoStartEnabled, setAutoStart } from '~/utils/autoStart'
import { IRPCActionType, IRPCType } from '~/utils/enum'
const STORE_PATH = dbPathDir()
@@ -59,9 +60,14 @@ export default [
{
action: IRPCActionType.PICLIST_AUTO_START,
handler: async (_: IIPCEvent, args: [val: boolean]) => {
app.setLoginItemSettings({
openAtLogin: args[0]
})
await setAutoStart(args[0])
}
},
{
action: IRPCActionType.PICLIST_AUTO_START_STATUS,
handler: async (_: IIPCEvent) => {
return await isAutoStartEnabled()
},
type: IRPCType.INVOKE
}
]

View File

@@ -26,6 +26,7 @@ import getManageApi from '~/manage/Main'
import { clearTempFolder } from '~/manage/utils/common'
import server from '~/server/index'
import webServer from '~/server/webServer'
import { isAutoStartEnabled, setAutoStart } from '~/utils/autoStart'
import beforeOpen from '~/utils/beforeOpen'
import clipboardPoll from '~/utils/clipboardPoll'
import { configPaths } from '~/utils/configPaths'
@@ -291,9 +292,24 @@ class LifeCycle {
windowManager.create(IWindowList.SETTING_WINDOW)
}
})
app.setLoginItemSettings({
openAtLogin: db.get(configPaths.settings.autoStart) || false
})
const storedAutoStartEnabled = db.get(configPaths.settings.autoStart) || false
isAutoStartEnabled()
.then(actualAutoStartEnabled => {
if (actualAutoStartEnabled !== storedAutoStartEnabled) {
logger.warn(
`Auto-start state mismatch detected. Stored: ${storedAutoStartEnabled}, Actual: ${actualAutoStartEnabled}. Syncing...`
)
setAutoStart(storedAutoStartEnabled).catch(err => {
logger.error('Failed to sync auto-start:', err)
})
}
})
.catch(err => {
logger.error('Failed to check auto-start status:', err)
setAutoStart(storedAutoStartEnabled).catch(fallbackErr => {
logger.error('Failed to set auto-start as fallback:', fallbackErr)
})
})
if (process.platform === 'win32') {
app.setAppUserModelId('com.kuingsmile.piclist')
}

View File

@@ -0,0 +1,60 @@
import os from 'node:os'
import path from 'node:path'
import { app } from 'electron'
import fs from 'fs-extra'
export const setAutoStart = async (enable: boolean): Promise<void> => {
try {
if (process.platform !== 'linux') {
app.setLoginItemSettings({
openAtLogin: enable
})
return
}
const autostartDir = path.join(os.homedir(), '.config', 'autostart')
const desktopFile = path.join(autostartDir, 'piclist.desktop')
if (enable) {
await fs.ensureDir(autostartDir)
const execPath = process.execPath
const desktopContent = `[Desktop Entry]
Name=PicList
Exec=${execPath} %U
Terminal=false
Type=Application
Icon=piclist
StartupWMClass=PicList
X-AppImage-Version=${app.getVersion()}
Comment=A powerful cloud storage manage tool.
Categories=Utility;
StartupNotify=true
`
await fs.writeFile(desktopFile, desktopContent, 'utf8')
await fs.chmod(desktopFile, 0o755)
} else {
if (await fs.pathExists(desktopFile)) {
await fs.remove(desktopFile)
}
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
throw new Error(`Failed to ${enable ? 'enable' : 'disable'} auto-start: ${errorMessage}`)
}
}
export const isAutoStartEnabled = async (): Promise<boolean> => {
try {
if (process.platform !== 'linux') {
return app.getLoginItemSettings().openAtLogin
}
const autostartDir = path.join(os.homedir(), '.config', 'autostart')
const desktopFile = path.join(autostartDir, 'piclist.desktop')
return fs.pathExists(desktopFile)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
throw new Error(`Failed to check auto-start status: ${errorMessage}`)
}
}

View File

@@ -110,6 +110,7 @@ export const IRPCActionType = {
PICLIST_OPEN_FILE: 'PICLIST_OPEN_FILE',
PICLIST_OPEN_DIRECTORY: 'PICLIST_OPEN_DIRECTORY',
PICLIST_AUTO_START: 'PICLIST_AUTO_START',
PICLIST_AUTO_START_STATUS: 'PICLIST_AUTO_START_STATUS',
// shortkey setting rpc
SHORTKEY_UPDATE: 'SHORTKEY_UPDATE',

View File

@@ -1607,6 +1607,17 @@ async function initData() {
formKeys.forEach(key => {
;(formOfSetting.value as any)[key] = settings[key] ?? formOfSetting.value[key]
})
try {
const actualAutoStartStatus = await window.electron.triggerRPC<boolean>(IRPCActionType.PICLIST_AUTO_START_STATUS)
if (typeof actualAutoStartStatus === 'boolean') {
formOfSetting.value.autoStart = actualAutoStartStatus
if (actualAutoStartStatus !== settings.autoStart) {
saveConfig({ [configPaths.settings.autoStart]: actualAutoStartStatus })
}
}
} catch (error) {
formOfSetting.value.autoStart = settings.autoStart ?? false
}
formOfSetting.value.logLevel = initArray(settings.logLevel || [], ['all'])
formOfSetting.value.autoImportPicBed = initArray(settings.autoImportPicBed || [], [])
currentLanguage.value = settings.language || 'zh-CN'

View File

@@ -57,6 +57,7 @@ export const IRPCActionType = {
PICLIST_OPEN_FILE: 'PICLIST_OPEN_FILE',
PICLIST_OPEN_DIRECTORY: 'PICLIST_OPEN_DIRECTORY',
PICLIST_AUTO_START: 'PICLIST_AUTO_START',
PICLIST_AUTO_START_STATUS: 'PICLIST_AUTO_START_STATUS',
// shortkey setting rpc
SHORTKEY_UPDATE: 'SHORTKEY_UPDATE',