优化
This commit is contained in:
265
EXIT_FUNCTION_FIX.md
Normal file
265
EXIT_FUNCTION_FIX.md
Normal file
@@ -0,0 +1,265 @@
|
||||
# 应用退出功能修复说明
|
||||
|
||||
## 问题描述
|
||||
点击系统托盘区的"退出"时,任务管理器里面还有残余进程没有完全退出,导致再次点击图标时打不开应用程序。
|
||||
|
||||
## 问题原因分析
|
||||
1. **退出方法不当**:使用了 `app.quit()` 而不是 `app.exit()`,导致应用没有完全退出
|
||||
2. **窗口销毁不完整**:窗口销毁和进程退出之间没有足够的延迟
|
||||
3. **退出事件处理不当**:多个退出事件处理器可能相互冲突
|
||||
4. **进程残留**:应用异常退出时,子进程没有正确清理
|
||||
|
||||
## 修复内容
|
||||
|
||||
### 1. 修复托盘退出功能 (`src/main/tray.js`)
|
||||
|
||||
**修复前:**
|
||||
```javascript
|
||||
{
|
||||
label: '退出应用',
|
||||
click: () => {
|
||||
app.isQuiting = true
|
||||
// 确保所有窗口都被关闭
|
||||
BrowserWindow.getAllWindows().forEach(window => {
|
||||
window.destroy()
|
||||
})
|
||||
app.quit()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**修复后:**
|
||||
```javascript
|
||||
{
|
||||
label: '退出应用',
|
||||
click: () => {
|
||||
logger.info('用户点击退出应用')
|
||||
app.isQuiting = true
|
||||
|
||||
// 确保所有窗口都被关闭
|
||||
const windows = BrowserWindow.getAllWindows()
|
||||
logger.info(`准备关闭 ${windows.length} 个窗口`)
|
||||
|
||||
windows.forEach(window => {
|
||||
if (!window.isDestroyed()) {
|
||||
try {
|
||||
window.destroy()
|
||||
logger.info('窗口销毁成功')
|
||||
} catch (error) {
|
||||
logger.warn('销毁窗口时出错:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 延迟执行退出,确保窗口销毁完成
|
||||
setTimeout(() => {
|
||||
try {
|
||||
logger.info('执行应用退出')
|
||||
// 使用 exit 而不是 quit,确保完全退出
|
||||
app.exit(0)
|
||||
} catch (error) {
|
||||
logger.error('应用退出失败,尝试强制退出:', error)
|
||||
try {
|
||||
process.exit(0)
|
||||
} catch (processError) {
|
||||
logger.error('强制退出也失败:', processError)
|
||||
// 最后的强制退出
|
||||
process.kill(process.pid, 'SIGKILL')
|
||||
}
|
||||
}
|
||||
}, 500) // 延迟500ms确保窗口销毁完成
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 修复主进程退出逻辑 (`src/main/index.js`)
|
||||
|
||||
**修复前:**
|
||||
```javascript
|
||||
app.on('window-all-closed', async (event) => {
|
||||
// ...
|
||||
if (!app.isQuiting) {
|
||||
// 隐藏窗口
|
||||
app.quit()
|
||||
} else {
|
||||
// 主动退出
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('before-quit', async (event) => {
|
||||
// ...
|
||||
app.quit()
|
||||
})
|
||||
|
||||
app.on('will-quit', async (event) => {
|
||||
// ...
|
||||
app.quit()
|
||||
})
|
||||
```
|
||||
|
||||
**修复后:**
|
||||
```javascript
|
||||
app.on('window-all-closed', async (event) => {
|
||||
// ...
|
||||
if (!app.isQuiting) {
|
||||
logger.info('用户关闭窗口,隐藏应用')
|
||||
// 隐藏窗口
|
||||
app.quit()
|
||||
} else {
|
||||
logger.info('主动退出,完全关闭应用')
|
||||
// 使用 exit 确保完全退出
|
||||
app.exit(0)
|
||||
}
|
||||
})
|
||||
|
||||
app.on('before-quit', async (event) => {
|
||||
logger.info('应用即将退出,开始清理资源')
|
||||
// ...
|
||||
// 使用 exit 确保完全退出
|
||||
app.exit(0)
|
||||
})
|
||||
|
||||
app.on('will-quit', async (event) => {
|
||||
logger.info('应用即将退出,注销快捷键')
|
||||
// ...
|
||||
// 使用 exit 确保完全退出
|
||||
app.exit(0)
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 创建清理工具
|
||||
|
||||
#### `force-kill-processes.js` - 强制清理进程脚本
|
||||
```javascript
|
||||
// 查找并终止所有相关进程
|
||||
const processes = [
|
||||
'龙岗区百千万AI智能体共创平台.exe',
|
||||
'dify-market-manager-gui.exe',
|
||||
'electron.exe'
|
||||
]
|
||||
|
||||
for (const processName of processes) {
|
||||
// 查找进程
|
||||
const findResult = execSync(`tasklist /FI "IMAGENAME eq ${processName}" /FO CSV /NH`)
|
||||
|
||||
if (findResult.includes(processName)) {
|
||||
// 终止进程
|
||||
execSync(`taskkill /F /IM "${processName}"`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `test-exit-function.js` - 退出功能测试脚本
|
||||
```javascript
|
||||
// 测试托盘退出功能
|
||||
{
|
||||
label: '退出应用',
|
||||
click: () => {
|
||||
console.log('用户点击退出应用')
|
||||
|
||||
// 确保所有窗口都被关闭
|
||||
const windows = BrowserWindow.getAllWindows()
|
||||
windows.forEach(window => {
|
||||
if (!window.isDestroyed()) {
|
||||
window.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
// 延迟执行退出
|
||||
setTimeout(() => {
|
||||
app.exit(0)
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 修复后的功能特点
|
||||
|
||||
### 1. 完全退出
|
||||
- 使用 `app.exit(0)` 替代 `app.quit()`
|
||||
- 确保所有窗口完全销毁后再退出
|
||||
- 添加延迟确保资源清理完成
|
||||
|
||||
### 2. 多层退出保护
|
||||
- 托盘退出:`app.exit(0)`
|
||||
- 主进程退出:`app.exit(0)`
|
||||
- 异常退出:`process.exit(0)`
|
||||
- 强制退出:`process.kill(process.pid, 'SIGKILL')`
|
||||
|
||||
### 3. 详细日志记录
|
||||
- 记录退出过程的每个步骤
|
||||
- 便于调试和问题排查
|
||||
- 区分不同类型的退出
|
||||
|
||||
### 4. 进程清理工具
|
||||
- 自动查找相关进程
|
||||
- 强制终止残留进程
|
||||
- 验证清理结果
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 正常退出
|
||||
1. 右键点击系统托盘图标
|
||||
2. 选择"退出应用"
|
||||
3. 应用将完全退出,无进程残留
|
||||
|
||||
### 2. 清理残留进程
|
||||
```bash
|
||||
# 强制清理所有相关进程
|
||||
node force-kill-processes.js
|
||||
|
||||
# 清理锁文件
|
||||
node cleanup-lock-files.js
|
||||
```
|
||||
|
||||
### 3. 测试退出功能
|
||||
```bash
|
||||
# 运行测试脚本
|
||||
node test-exit-function.js
|
||||
```
|
||||
|
||||
## 验证修复效果
|
||||
|
||||
### 1. 正常退出
|
||||
```
|
||||
[时间] 用户点击退出应用
|
||||
[时间] 准备关闭 1 个窗口
|
||||
[时间] 窗口销毁成功
|
||||
[时间] 执行应用退出
|
||||
```
|
||||
|
||||
### 2. 进程检查
|
||||
```bash
|
||||
# 检查是否还有相关进程
|
||||
tasklist /FI "IMAGENAME eq 龙岗区百千万AI智能体共创平台.exe"
|
||||
# 应该显示:INFO: No tasks are running which match the specified criteria.
|
||||
```
|
||||
|
||||
### 3. 重新启动
|
||||
- 退出后重新点击应用图标
|
||||
- 应该能正常启动,无单实例冲突
|
||||
|
||||
## 注意事项
|
||||
|
||||
### 1. 退出时机
|
||||
- 确保所有窗口完全销毁后再退出
|
||||
- 添加适当的延迟避免资源冲突
|
||||
|
||||
### 2. 异常处理
|
||||
- 提供多层退出保护机制
|
||||
- 记录详细的退出日志
|
||||
|
||||
### 3. 进程清理
|
||||
- 定期检查是否有残留进程
|
||||
- 使用清理工具处理异常情况
|
||||
|
||||
## 相关文件
|
||||
- `src/main/tray.js` - 托盘功能(已修复退出逻辑)
|
||||
- `src/main/index.js` - 主进程(已修复退出事件)
|
||||
- `force-kill-processes.js` - 强制清理进程脚本
|
||||
- `test-exit-function.js` - 退出功能测试脚本
|
||||
- `cleanup-lock-files.js` - 锁文件清理脚本
|
||||
|
||||
## 总结
|
||||
通过使用 `app.exit(0)` 替代 `app.quit()`、添加窗口销毁延迟、提供多层退出保护机制,成功解决了应用退出时进程残留的问题。现在点击托盘"退出应用"后,应用将完全退出,无进程残留,可以正常重新启动。
|
||||
Reference in New Issue
Block a user