()
| 80 | |
| 81 | // 启动监听 |
| 82 | private startWatching(): void { |
| 83 | // 根据平台设置监听目录 |
| 84 | const watchPaths = this.getWatchPaths() |
| 85 | |
| 86 | console.log('[AppWatcher] 开始监听应用目录变化:', watchPaths) |
| 87 | |
| 88 | const isWindows = process.platform === 'win32' |
| 89 | |
| 90 | // 创建监听器 |
| 91 | this.watcher = chokidar.watch(watchPaths, { |
| 92 | // Windows 需要递归监听子目录,macOS 只需要一级 |
| 93 | depth: isWindows ? 5 : 1, |
| 94 | // 根据平台设置忽略规则 |
| 95 | ignored: (filePath: string) => { |
| 96 | return this.shouldIgnore(filePath, watchPaths) |
| 97 | }, |
| 98 | // 持久化监听 |
| 99 | persistent: true, |
| 100 | // 忽略初始添加事件(避免启动时触发大量事件) |
| 101 | ignoreInitial: true, |
| 102 | // Windows 使用轮询避免 fs.watch 占用文件夹句柄导致无法重命名/删除 |
| 103 | usePolling: isWindows, |
| 104 | interval: isWindows ? 5000 : undefined, |
| 105 | binaryInterval: isWindows ? 5000 : undefined, |
| 106 | // 监听文件夹事件 |
| 107 | followSymlinks: false, |
| 108 | // 避免在 macOS 上出现问题 |
| 109 | awaitWriteFinish: { |
| 110 | stabilityThreshold: 500, |
| 111 | pollInterval: 100 |
| 112 | } |
| 113 | }) |
| 114 | |
| 115 | // 监听添加事件 |
| 116 | if (process.platform === 'win32') { |
| 117 | // Windows: 监听 .lnk 文件 |
| 118 | this.watcher.on('add', (filePath: string) => { |
| 119 | if (filePath.endsWith('.lnk')) { |
| 120 | console.log('[AppWatcher] 检测到新快捷方式:', filePath) |
| 121 | this.notifyChange('add', filePath) |
| 122 | } |
| 123 | }) |
| 124 | } |
| 125 | |
| 126 | if (process.platform === 'darwin') { |
| 127 | // macOS: 监听 .app 目录 |
| 128 | this.watcher.on('addDir', (filePath: string) => { |
| 129 | if (filePath.endsWith('.app')) { |
| 130 | console.log('[AppWatcher] 检测到新应用:', filePath) |
| 131 | this.notifyChange('add', filePath) |
| 132 | } |
| 133 | }) |
| 134 | } |
| 135 | |
| 136 | // 监听删除事件 |
| 137 | if (process.platform === 'win32') { |
| 138 | // Windows: 监听 .lnk 文件删除 |
| 139 | this.watcher.on('unlink', (filePath: string) => { |
no test coverage detected