diff --git a/assets/logos/farmcontrolinstaller.png b/assets/logos/farmcontrolinstaller.png new file mode 100644 index 0000000..fad5f5d Binary files /dev/null and b/assets/logos/farmcontrolinstaller.png differ diff --git a/scripts/patch-electrobun-src.mjs b/scripts/patch-electrobun-src.mjs index 999c2b6..0656823 100644 --- a/scripts/patch-electrobun-src.mjs +++ b/scripts/patch-electrobun-src.mjs @@ -283,23 +283,56 @@ function patchNativeWrapperPath(nativeTsPath) { } let source = readFileSync(nativeTsPath, 'utf8') - const needle = - 'const nativeWrapperPath = join(process.cwd(), `libNativeWrapper.${suffix}`);' - const replacement = - 'const nativeWrapperPath = join(dirname(process.execPath), `libNativeWrapper.${suffix}`);' - if (!source.includes(needle)) { + if (source.includes('function resolveNativeWrapperPath()')) { return } - if (!source.includes('dirname')) { + if (!source.includes('existsSync')) { + if (source.includes('import { dirname, join } from "path";')) { + source = source.replace( + 'import { dirname, join } from "path";', + 'import { existsSync } from "fs";\nimport { dirname, join } from "path";' + ) + } else { + source = source.replace( + 'import { join } from "path";', + 'import { existsSync } from "fs";\nimport { dirname, join } from "path";' + ) + } + } else if (!source.includes('dirname')) { source = source.replace( 'import { join } from "path";', 'import { dirname, join } from "path";' ) } - source = source.replace(needle, replacement) + const helper = ` +function resolveNativeWrapperPath() { +\tconst fileName = \`libNativeWrapper.\${suffix}\`; +\tconst candidates = [ +\t\tjoin(dirname(process.execPath), fileName), +\t\tjoin(process.cwd(), fileName), +\t]; +\tfor (const candidate of candidates) { +\t\tif (existsSync(candidate)) { +\t\t\treturn candidate; +\t\t} +\t} +\treturn candidates[0]!; +} +` + + source = source.replace( + 'export const native = (() => {', + `${helper}\nexport const native = (() => {` + ) + + source = source.replace( + /const nativeWrapperPath = join\((?:dirname\(process\.execPath\)|process\.cwd\(\)), `libNativeWrapper\.\$\{suffix\}`\);/, + 'const nativeWrapperPath = resolveNativeWrapperPath();' + ) + writeFileSync(nativeTsPath, source) } diff --git a/src/bun/index.js b/src/bun/index.js index 3d95789..847d149 100644 --- a/src/bun/index.js +++ b/src/bun/index.js @@ -1,18 +1,11 @@ -import { chdirSync } from 'node:fs' -import { dirname } from 'node:path' +import { ensureWindowsWorkingDirectory } from '../desktop/windows-app-paths.js' import { captureLaunchUrl, closeSingleInstanceServer, ensureSingleInstanceLock } from '../desktop/single-instance.js' -if (process.platform === 'win32') { - try { - chdirSync(dirname(process.execPath)) - } catch { - // Best effort; some launchers may not allow changing directory. - } -} +ensureWindowsWorkingDirectory() const launchUrl = captureLaunchUrl() const gotSingleInstanceLock = await ensureSingleInstanceLock({ launchUrl }) diff --git a/src/desktop/windows-app-paths.js b/src/desktop/windows-app-paths.js new file mode 100644 index 0000000..e3511e6 --- /dev/null +++ b/src/desktop/windows-app-paths.js @@ -0,0 +1,42 @@ +import { chdirSync, existsSync } from 'node:fs' +import { dirname, join } from 'node:path' + +const NATIVE_WRAPPER_DLL = 'libNativeWrapper.dll' + +export function resolveWindowsBinDir() { + const candidates = [ + dirname(process.execPath), + process.cwd(), + join(dirname(process.execPath), 'bin'), + join(process.cwd(), 'bin') + ] + + for (const candidate of candidates) { + if ( + existsSync(join(candidate, 'launcher.exe')) || + existsSync(join(candidate, NATIVE_WRAPPER_DLL)) + ) { + return candidate + } + } + + return dirname(process.execPath) +} + +export function ensureWindowsWorkingDirectory() { + if (process.platform !== 'win32') { + return + } + + const binDir = resolveWindowsBinDir() + const wrapperInCwd = existsSync(join(process.cwd(), NATIVE_WRAPPER_DLL)) + const wrapperInBinDir = existsSync(join(binDir, NATIVE_WRAPPER_DLL)) + + if (!wrapperInCwd && wrapperInBinDir) { + try { + chdirSync(binDir) + } catch { + // Ignore if we cannot change directory. + } + } +}