feat: Phase 6 - auto-detect native exes from original app paths

This commit is contained in:
Chen Gu
2026-05-09 19:22:09 +08:00
parent 3142ccc762
commit 459fe31ad3
2 changed files with 74 additions and 36 deletions

View File

@@ -45,22 +45,38 @@ let mainWindow = null;
let overlayProcess = null; let overlayProcess = null;
let monitorProcess = null; let monitorProcess = null;
// --- 工具路径 --- // --- 工具路径 ---
function getToolsDir() { // 多种可能的路径,适配原版解包和开发环境
// 开发模式exe 在项目根目录下的 resources/tools/ function findExe(name) {
const searchPaths = [];
// 开发模式:项目根目录
if (process.env.VITE_DEV_SERVER_URL) { if (process.env.VITE_DEV_SERVER_URL) {
const devPath = path.join(electron_1.app.getAppPath(), 'resources', 'tools'); const devBase = path.join(electron_1.app.getAppPath(), 'resources');
if (fs.existsSync(devPath)) searchPaths.push(path.join(devBase, name));
return devPath; searchPaths.push(path.join(devBase, 'tools', name));
// 备选:当前目录的 resources/tools/ searchPaths.push(path.join(devBase, 'tools', 'xixi-overlay-helper', name));
const cwdPath = path.join(process.cwd(), 'resources', 'tools'); searchPaths.push(path.join(process.cwd(), 'resources', name));
if (fs.existsSync(cwdPath)) searchPaths.push(path.join(process.cwd(), 'resources', 'tools', name));
return cwdPath;
} }
// 生产模式exe 在 resources/tools/ 下 // 生产模式
return path.join(process.resourcesPath, 'tools'); searchPaths.push(path.join(process.resourcesPath, name));
} searchPaths.push(path.join(process.resourcesPath, 'tools', name));
function exePath(name) { searchPaths.push(path.join(process.resourcesPath, 'tools', 'xixi-overlay-helper', name));
return path.join(getToolsDir(), name); // 额外:直接检查可能的路径
searchPaths.push(path.join(electron_1.app.getAppPath(), 'resources', name));
searchPaths.push(path.join(electron_1.app.getAppPath(), 'resources', 'tools', name));
for (const p of searchPaths) {
const exePath = p.endsWith('.exe') ? p : p + '.exe';
if (fs.existsSync(exePath)) {
console.log('[main] Found:', exePath);
return exePath;
}
if (fs.existsSync(p)) {
console.log('[main] Found:', p);
return p;
}
}
console.warn('[main] NOT found:', name);
return path.join(electron_1.app.getAppPath(), 'resources', 'tools', name); // fallback
} }
// --- 窗口 --- // --- 窗口 ---
function createWindow() { function createWindow() {
@@ -106,7 +122,7 @@ electron_1.ipcMain.handle('optimize:list', async () => {
}); });
electron_1.ipcMain.handle('optimize:item', async (_event, id) => { electron_1.ipcMain.handle('optimize:item', async (_event, id) => {
try { try {
const h1Exe = exePath('MaqiangTangh1.exe'); const h1Exe = findExe('MaqiangTangh1.exe');
if (!fs.existsSync(h1Exe)) { if (!fs.existsSync(h1Exe)) {
console.warn(`[optimize] h1.exe not found at ${h1Exe}, using simulation`); console.warn(`[optimize] h1.exe not found at ${h1Exe}, using simulation`);
await new Promise(r => setTimeout(r, 1000)); await new Promise(r => setTimeout(r, 1000));
@@ -121,7 +137,7 @@ electron_1.ipcMain.handle('optimize:item', async (_event, id) => {
}); });
electron_1.ipcMain.handle('optimize:restore', async (_event, id) => { electron_1.ipcMain.handle('optimize:restore', async (_event, id) => {
try { try {
const h1Exe = exePath('MaqiangTangh1.exe'); const h1Exe = findExe('MaqiangTangh1.exe');
if (!fs.existsSync(h1Exe)) { if (!fs.existsSync(h1Exe)) {
await new Promise(r => setTimeout(r, 1000)); await new Promise(r => setTimeout(r, 1000));
return { success: true, id, action: 'restored' }; return { success: true, id, action: 'restored' };
@@ -140,7 +156,7 @@ electron_1.ipcMain.handle('overlay:start', async (_event, options) => {
overlayProcess.kill(); overlayProcess.kill();
overlayProcess = null; overlayProcess = null;
} }
const overlayExe = exePath('MaqiangTangXiXiOverlay.exe'); const overlayExe = findExe('MaqiangTangXiXiOverlay.exe');
if (!fs.existsSync(overlayExe)) { if (!fs.existsSync(overlayExe)) {
return { success: false, error: `Overlay exe not found at ${overlayExe}` }; return { success: false, error: `Overlay exe not found at ${overlayExe}` };
} }
@@ -178,7 +194,7 @@ electron_1.ipcMain.handle('monitor:start', async () => {
monitorProcess.kill(); monitorProcess.kill();
monitorProcess = null; monitorProcess = null;
} }
const monExe = exePath('MaqiangTangHardwareMonitor.exe'); const monExe = findExe('MaqiangTangHardwareMonitor.exe');
if (!fs.existsSync(monExe)) { if (!fs.existsSync(monExe)) {
return { success: false, error: `Monitor exe not found at ${monExe}` }; return { success: false, error: `Monitor exe not found at ${monExe}` };
} }

View File

@@ -13,21 +13,43 @@ let overlayProcess: ChildProcess | null = null;
let monitorProcess: ChildProcess | null = null; let monitorProcess: ChildProcess | null = null;
// --- 工具路径 --- // --- 工具路径 ---
function getToolsDir(): string { // 多种可能的路径,适配原版解包和开发环境
// 开发模式exe 在项目根目录下的 resources/tools/ function findExe(name: string): string {
if (process.env.VITE_DEV_SERVER_URL) { const searchPaths: string[] = [];
const devPath = path.join(app.getAppPath(), 'resources', 'tools');
if (fs.existsSync(devPath)) return devPath;
// 备选:当前目录的 resources/tools/
const cwdPath = path.join(process.cwd(), 'resources', 'tools');
if (fs.existsSync(cwdPath)) return cwdPath;
}
// 生产模式exe 在 resources/tools/ 下
return path.join(process.resourcesPath, 'tools');
}
function exePath(name: string): string { // 开发模式:项目根目录
return path.join(getToolsDir(), name); if (process.env.VITE_DEV_SERVER_URL) {
const devBase = path.join(app.getAppPath(), 'resources');
searchPaths.push(path.join(devBase, name));
searchPaths.push(path.join(devBase, 'tools', name));
searchPaths.push(path.join(devBase, 'tools', 'xixi-overlay-helper', name));
searchPaths.push(path.join(process.cwd(), 'resources', name));
searchPaths.push(path.join(process.cwd(), 'resources', 'tools', name));
}
// 生产模式
searchPaths.push(path.join(process.resourcesPath, name));
searchPaths.push(path.join(process.resourcesPath, 'tools', name));
searchPaths.push(path.join(process.resourcesPath, 'tools', 'xixi-overlay-helper', name));
// 额外:直接检查可能的路径
searchPaths.push(path.join(app.getAppPath(), 'resources', name));
searchPaths.push(path.join(app.getAppPath(), 'resources', 'tools', name));
for (const p of searchPaths) {
const exePath = p.endsWith('.exe') ? p : p + '.exe';
if (fs.existsSync(exePath)) {
console.log('[main] Found:', exePath);
return exePath;
}
if (fs.existsSync(p)) {
console.log('[main] Found:', p);
return p;
}
}
console.warn('[main] NOT found:', name);
return path.join(app.getAppPath(), 'resources', 'tools', name); // fallback
} }
// --- 窗口 --- // --- 窗口 ---
@@ -79,7 +101,7 @@ ipcMain.handle('optimize:list', async () => {
ipcMain.handle('optimize:item', async (_event, id: string) => { ipcMain.handle('optimize:item', async (_event, id: string) => {
try { try {
const h1Exe = exePath('MaqiangTangh1.exe'); const h1Exe = findExe('MaqiangTangh1.exe');
if (!fs.existsSync(h1Exe)) { if (!fs.existsSync(h1Exe)) {
console.warn(`[optimize] h1.exe not found at ${h1Exe}, using simulation`); console.warn(`[optimize] h1.exe not found at ${h1Exe}, using simulation`);
await new Promise(r => setTimeout(r, 1000)); await new Promise(r => setTimeout(r, 1000));
@@ -94,7 +116,7 @@ ipcMain.handle('optimize:item', async (_event, id: string) => {
ipcMain.handle('optimize:restore', async (_event, id: string) => { ipcMain.handle('optimize:restore', async (_event, id: string) => {
try { try {
const h1Exe = exePath('MaqiangTangh1.exe'); const h1Exe = findExe('MaqiangTangh1.exe');
if (!fs.existsSync(h1Exe)) { if (!fs.existsSync(h1Exe)) {
await new Promise(r => setTimeout(r, 1000)); await new Promise(r => setTimeout(r, 1000));
return { success: true, id, action: 'restored' }; return { success: true, id, action: 'restored' };
@@ -113,7 +135,7 @@ ipcMain.handle('overlay:start', async (_event, options?: any) => {
overlayProcess.kill(); overlayProcess.kill();
overlayProcess = null; overlayProcess = null;
} }
const overlayExe = exePath('MaqiangTangXiXiOverlay.exe'); const overlayExe = findExe('MaqiangTangXiXiOverlay.exe');
if (!fs.existsSync(overlayExe)) { if (!fs.existsSync(overlayExe)) {
return { success: false, error: `Overlay exe not found at ${overlayExe}` }; return { success: false, error: `Overlay exe not found at ${overlayExe}` };
} }
@@ -154,7 +176,7 @@ ipcMain.handle('monitor:start', async () => {
monitorProcess.kill(); monitorProcess.kill();
monitorProcess = null; monitorProcess = null;
} }
const monExe = exePath('MaqiangTangHardwareMonitor.exe'); const monExe = findExe('MaqiangTangHardwareMonitor.exe');
if (!fs.existsSync(monExe)) { if (!fs.existsSync(monExe)) {
return { success: false, error: `Monitor exe not found at ${monExe}` }; return { success: false, error: `Monitor exe not found at ${monExe}` };
} }