[EXPERIMENTAL] linux apps support

This commit is contained in:
olcxja 2026-10-06 20:54:16 +02:00
commit e7636afe3d
20 changed files with 1377 additions and 101 deletions

View file

@ -2,6 +2,7 @@
const fs = require('fs')
const path = require('path')
const { desktopFileFor, readDesktopEntry, findIconFile, pngOrSvg } = require('./linuxapp')
function rvaToOffset(sections, rva) {
for (const s of sections) {
@ -208,4 +209,35 @@ function extractIconFromExe(exePath, outPath) {
}
}
module.exports = { extractIconFromExe, parseIcons, buildIco }
// Native Linux apps carry no icon inside the binary: it comes from the
// .desktop entry (Icon=), an image next to the program, or the theme.
// `outBase` is a path without extension; the sniffed one is appended.
function iconFromLinuxApp(exePath, outBase) {
try {
const desktop = desktopFileFor(exePath)
const entry = desktop ? readDesktopEntry(desktop) : null
const baseDir = desktop ? path.dirname(desktop) : path.dirname(exePath)
let source = findIconFile(entry && entry.Icon, baseDir)
if (!source) {
// no .desktop: a same-named image (or the AppImage .DirIcon) next to it
const dir = path.dirname(exePath)
const stem = path.basename(exePath).replace(/\.(appimage|sh|bin)$/i, '')
for (const name of [stem + '.png', stem + '.svg', '.DirIcon', 'icon.png', 'icon.svg']) {
const candidate = path.join(dir, name)
if (pngOrSvg(candidate)) {
source = candidate
break
}
}
}
if (!source) return { ok: false, error: 'no-icon' }
const outPath = `${outBase}.${pngOrSvg(source)}`
fs.mkdirSync(path.dirname(outPath), { recursive: true })
fs.copyFileSync(source, outPath)
return { ok: true, path: outPath }
} catch (err) {
return { ok: false, error: String((err && err.message) || err) }
}
}
module.exports = { extractIconFromExe, iconFromLinuxApp, parseIcons, buildIco }