Add app launcher job handling and update app stats structure

This commit is contained in:
2026-10-11 23:49:46 -04:00
parent 8b8795a475
commit ba51b6bf99
3 changed files with 351 additions and 123 deletions
+32
View File
@@ -0,0 +1,32 @@
# Repository Guidelines
## Project Structure & Module Organization
The Stream Deck plugin lives in `dynamic-deck/`; run its commands from that directory. TypeScript entrypoint and action handlers are in `src/plugin.ts` and `src/actions/`, shared logic is in `src/services/` and `src/utils/`, and Property Inspector files are in `src/ui/`. Artwork is under `imgs/`. `com.ryan-kegel.dynamic-deck.sdPlugin/` is the Stream Deck bundle; Rollup writes the plugin bundle there and copies UI and supporting assets. The nested `dynamic-deck/AGENTS.md` has detailed implementation notes; follow it when changing that project.
## Build, Test, and Development Commands
From `dynamic-deck/`:
- `npm install` installs the plugin dependencies.
- `npm run build` creates the production bundle at `com.ryan-kegel.dynamic-deck.sdPlugin/bin/plugin.js`.
- `npm run watch` rebuilds on changes and asks the Stream Deck CLI to restart the plugin.
- `node generate-assets.cjs` creates placeholder PNG assets if they are missing.
There is no configured test runner, linter, or standalone typecheck script. Use the build to check plugin compilation; do not run `tsc` directly.
## Coding Style & Naming Conventions
Use TypeScript ES modules, two-space indentation in TypeScript and Rollup configuration, and descriptive kebab-case filenames (for example, `app-monitor.ts`). Keep each Stream Deck action in its own file under `src/actions/`, and match its registered UUID to the plugin ID in the manifest. Update source files under `src/`; generated bundle files are build output. Some app discovery and window-focus features rely on Windows PowerShell and Win32 APIs.
## Testing Guidelines
No automated tests or coverage requirements are configured. For changes to plugin code, run `npm run build` from `dynamic-deck/` and inspect the generated bundle or test the action in Stream Deck when available. UI changes should be checked in the corresponding Property Inspector.
## Commit & Pull Request Guidelines
Git history currently contains only the initial commit, so no commit convention is established. Use a short, imperative summary (for example, `Fix app launcher title sync`). Pull requests should explain the behavior change, list relevant verification steps, link related issues, and include screenshots for visible Property Inspector or key-face changes.
## Configuration & Runtime Data
Keep API credentials in Stream Deck action settings, not committed files. The app tracker persists runtime statistics in `com.ryan-kegel.dynamic-deck.sdPlugin/app-stats.json`; avoid removing it unless resetting saved rankings is intended.
@@ -1,154 +1,330 @@
{ {
"c:\\portableapps\\visual studio code\\code.exe": { "d:\\python utilities\\icue\\app\\dist\\icue assigner\\icue assigner.exe": {
"name": "Visual Studio Code", "name": "icue assigner",
"path": "c:\\portableapps\\visual studio code\\code.exe", "path": "d:\\python utilities\\icue\\app\\dist\\icue assigner\\icue assigner.exe",
"launchCount": 12, "launchCount": 5,
"focusCount": 186, "focusCount": 7,
"activeDurationSeconds": 205450, "activeDurationSeconds": 436,
"lastUsedTimestamp": 1788926512701 "lastUsedTimestamp": 1791397964729
},
"c:\\program files\\google\\chrome\\application\\chrome.exe": {
"name": "Google Chrome",
"path": "c:\\program files\\google\\chrome\\application\\chrome.exe",
"launchCount": 34,
"focusCount": 253,
"activeDurationSeconds": 208334,
"lastUsedTimestamp": 1788926520418
},
"c:\\portableapps\\blender\\blender.exe": {
"name": "Blender",
"path": "c:\\portableapps\\blender\\blender.exe",
"launchCount": 2,
"focusCount": 2,
"activeDurationSeconds": 6,
"lastUsedTimestamp": 1788410154017
},
"c:\\godot4\\godot_v4.7.1-stable_win64.exe": {
"name": "Godot Engine",
"path": "c:\\godot4\\godot_v4.7.1-stable_win64.exe",
"launchCount": 115,
"focusCount": 83,
"activeDurationSeconds": 49481,
"lastUsedTimestamp": 1788919885095
}, },
"c:\\program files\\nomachine\\bin\\nxplayer.bin": { "c:\\program files\\nomachine\\bin\\nxplayer.bin": {
"name": "NoMachine Player Process", "name": "NoMachine Player Process",
"path": "c:\\program files\\nomachine\\bin\\nxplayer.bin", "path": "c:\\program files\\nomachine\\bin\\nxplayer.bin",
"launchCount": 5, "launchCount": 19,
"focusCount": 26, "focusCount": 125,
"activeDurationSeconds": 3607, "activeDurationSeconds": 36304,
"lastUsedTimestamp": 1788900860130 "lastUsedTimestamp": 1791776324356
}, },
"c:\\users\\ryan\\appdata\\local\\programs\\obsidian\\obsidian.exe": { "c:\\program files\\google\\chrome\\application\\chrome.exe": {
"name": "Obsidian", "name": "Google Chrome",
"path": "c:\\users\\ryan\\appdata\\local\\programs\\obsidian\\obsidian.exe", "path": "c:\\program files\\google\\chrome\\application\\chrome.exe",
"launchCount": 3, "launchCount": 66,
"focusCount": 28, "focusCount": 498,
"activeDurationSeconds": 2708, "activeDurationSeconds": 291389,
"lastUsedTimestamp": 1788924951152 "lastUsedTimestamp": 1791776318801
},
"c:\\portableapps\\visual studio code\\code.exe": {
"name": "Visual Studio Code",
"path": "c:\\portableapps\\visual studio code\\code.exe",
"launchCount": 10,
"focusCount": 569,
"activeDurationSeconds": 338873,
"lastUsedTimestamp": 1791776982303
}, },
"c:\\program files\\windowsapps\\microsoft.windowsterminal_1.24.11911.0_x64__8wekyb3d8bbwe\\windowsterminal.exe": { "c:\\program files\\windowsapps\\microsoft.windowsterminal_1.24.11911.0_x64__8wekyb3d8bbwe\\windowsterminal.exe": {
"name": "Windows Terminal Host", "name": "Windows Terminal Host",
"path": "c:\\program files\\windowsapps\\microsoft.windowsterminal_1.24.11911.0_x64__8wekyb3d8bbwe\\windowsterminal.exe", "path": "c:\\program files\\windowsapps\\microsoft.windowsterminal_1.24.11911.0_x64__8wekyb3d8bbwe\\windowsterminal.exe",
"launchCount": 3, "launchCount": 7,
"focusCount": 78, "focusCount": 185,
"activeDurationSeconds": 5848, "activeDurationSeconds": 110465,
"lastUsedTimestamp": 1788925695681 "lastUsedTimestamp": 1791776932626
}, },
"h:\\games\\the darkest files\\the darkest files.exe": { "c:\\godot4\\godot_v4.7.1-stable_win64.exe": {
"name": "the darkest files", "name": "Godot Engine",
"path": "h:\\games\\the darkest files\\the darkest files.exe", "path": "c:\\godot4\\godot_v4.7.1-stable_win64.exe",
"launchCount": 111,
"focusCount": 186,
"activeDurationSeconds": 49534,
"lastUsedTimestamp": 1791776950093
},
"c:\\python\\3.12.0\\python.exe": {
"name": "Python",
"path": "c:\\python\\3.12.0\\python.exe",
"launchCount": 51,
"focusCount": 132,
"activeDurationSeconds": 13038,
"lastUsedTimestamp": 1791734276556
},
"c:\\portableapps\\affinity publisher\\data\\local\\stubexe\\0xa311ff49a2412aaa\\publisher.exe": {
"name": "Turbo Virtual Machine Executable",
"path": "c:\\portableapps\\affinity publisher\\data\\local\\stubexe\\0xa311ff49a2412aaa\\publisher.exe",
"launchCount": 6,
"focusCount": 65,
"activeDurationSeconds": 1195,
"lastUsedTimestamp": 1791406867625
},
"c:\\portableapps\\affinity publisher\\data\\local\\stubexe\\0xff83c46c4db01a13\\notepad++.exe": {
"name": "Turbo Virtual Machine Executable",
"path": "c:\\portableapps\\affinity publisher\\data\\local\\stubexe\\0xff83c46c4db01a13\\notepad++.exe",
"launchCount": 2, "launchCount": 2,
"focusCount": 4, "focusCount": 7,
"activeDurationSeconds": 2381, "activeDurationSeconds": 25,
"lastUsedTimestamp": 1788838622190 "lastUsedTimestamp": 1791606075113
}, },
"c:\\portableapps\\gimpportable\\app\\gimp\\bin\\gimp-2.10.exe": { "c:\\program files (x86)\\microsoft\\edge\\application\\msedge.exe": {
"name": "GNU Image Manipulation Program", "name": "Microsoft Edge",
"path": "c:\\portableapps\\gimpportable\\app\\gimp\\bin\\gimp-2.10.exe", "path": "c:\\program files (x86)\\microsoft\\edge\\application\\msedge.exe",
"launchCount": 6,
"focusCount": 24,
"activeDurationSeconds": 629,
"lastUsedTimestamp": 1791406873658
},
"c:\\portableapps\\vlcportable3\\vlcportable.exe": {
"name": "VLC Media Player Portable (PortableApps.com Launcher)",
"path": "c:\\portableapps\\vlcportable3\\vlcportable.exe",
"launchCount": 19,
"focusCount": 19,
"activeDurationSeconds": 21,
"lastUsedTimestamp": 1791734352007
},
"c:\\portableapps\\vlcportable3\\app\\vlc\\vlc.exe": {
"name": "VLC media player",
"path": "c:\\portableapps\\vlcportable3\\app\\vlc\\vlc.exe",
"launchCount": 37,
"focusCount": 28,
"activeDurationSeconds": 1420,
"lastUsedTimestamp": 1791734502899
},
"c:\\program files\\vegas\\vegas pro 16.0\\vegas160.exe": {
"name": "VEGAS Pro",
"path": "c:\\program files\\vegas\\vegas pro 16.0\\vegas160.exe",
"launchCount": 2,
"focusCount": 12,
"activeDurationSeconds": 443,
"lastUsedTimestamp": 1791087959585
},
"c:\\program files\\7-zip\\7zg.exe": {
"name": "7-Zip GUI",
"path": "c:\\program files\\7-zip\\7zg.exe",
"launchCount": 1, "launchCount": 1,
"focusCount": 1, "focusCount": 1,
"activeDurationSeconds": 3, "activeDurationSeconds": 37,
"lastUsedTimestamp": 1788575227396 "lastUsedTimestamp": 1790980172911
}, },
"c:\\program files\\bambu studio\\bambu-studio.exe": { "c:\\program files\\windowsapps\\microsoft.gamingservices_38.117.27001.0_x64__8wekyb3d8bbwe\\gamingservicesui\\gamingservicesui.exe": {
"name": "BambuStudio", "name": "GamingServicesUI.exe",
"path": "c:\\program files\\bambu studio\\bambu-studio.exe", "path": "c:\\program files\\windowsapps\\microsoft.gamingservices_38.117.27001.0_x64__8wekyb3d8bbwe\\gamingservicesui\\gamingservicesui.exe",
"launchCount": 2, "launchCount": 4,
"focusCount": 9, "focusCount": 4,
"activeDurationSeconds": 27027, "activeDurationSeconds": 24,
"lastUsedTimestamp": 1788923561849 "lastUsedTimestamp": 1791773956910
},
"c:\\xboxgames\\minecraft launcher\\content\\minecraft.exe": {
"name": "minecraft",
"path": "c:\\xboxgames\\minecraft launcher\\content\\minecraft.exe",
"launchCount": 4,
"focusCount": 16,
"activeDurationSeconds": 358,
"lastUsedTimestamp": 1791776311763
},
"c:\\users\\ryan\\appdata\\local\\packages\\microsoft.4297127d64ec6_8wekyb3d8bbwe\\localcache\\local\\runtime\\java-runtime-epsilon\\windows-x64\\java-runtime-epsilon\\bin\\javaw.exe": {
"name": "OpenJDK Platform binary",
"path": "c:\\users\\ryan\\appdata\\local\\packages\\microsoft.4297127d64ec6_8wekyb3d8bbwe\\localcache\\local\\runtime\\java-runtime-epsilon\\windows-x64\\java-runtime-epsilon\\bin\\javaw.exe",
"launchCount": 6,
"focusCount": 12,
"activeDurationSeconds": 7640,
"lastUsedTimestamp": 1791776307738
},
"h:\\steam\\steamapps\\common\\among us\\among us.exe": {
"name": "among us",
"path": "h:\\steam\\steamapps\\common\\among us\\among us.exe",
"launchCount": 1,
"focusCount": 1,
"activeDurationSeconds": 22,
"lastUsedTimestamp": 1791084105438
},
"c:\\program files\\cheat engine\\cheatengine-x86_64.exe": {
"name": "Cheat Engine",
"path": "c:\\program files\\cheat engine\\cheatengine-x86_64.exe",
"launchCount": 1,
"focusCount": 2,
"activeDurationSeconds": 11,
"lastUsedTimestamp": 1791084325807
},
"c:\\program files (x86)\\steam\\steamapps\\common\\ravenfield\\ravenfield.exe": {
"name": "ravenfield",
"path": "c:\\program files (x86)\\steam\\steamapps\\common\\ravenfield\\ravenfield.exe",
"launchCount": 1,
"focusCount": 2,
"activeDurationSeconds": 2147,
"lastUsedTimestamp": 1791086272467
},
"c:\\portableapps\\affinity designer\\app\\designer\\designer.exe": {
"name": "Affinity Designer",
"path": "c:\\portableapps\\affinity designer\\app\\designer\\designer.exe",
"launchCount": 1,
"focusCount": 1,
"activeDurationSeconds": 111,
"lastUsedTimestamp": 1791088167181
},
"c:\\users\\ryan\\appdata\\local\\temp\\procexp64.exe": {
"name": "Sysinternals Process Explorer",
"path": "c:\\users\\ryan\\appdata\\local\\temp\\procexp64.exe",
"launchCount": 1,
"focusCount": 1,
"activeDurationSeconds": 92,
"lastUsedTimestamp": 1791088259775
},
"c:\\users\\ryan\\appdata\\local\\programs\\obsidian\\obsidian.exe": {
"name": "Obsidian",
"path": "c:\\users\\ryan\\appdata\\local\\programs\\obsidian\\obsidian.exe",
"launchCount": 4,
"focusCount": 27,
"activeDurationSeconds": 31202,
"lastUsedTimestamp": 1791737325568
},
"c:\\users\\ryan\\.codex\\packages\\app-server-daemon\\releases\\0.157.1-x86_64-pc-windows-msvc\\bin\\codex.exe": {
"name": "codex",
"path": "c:\\users\\ryan\\.codex\\packages\\app-server-daemon\\releases\\0.157.1-x86_64-pc-windows-msvc\\bin\\codex.exe",
"launchCount": 6,
"focusCount": 6,
"activeDurationSeconds": 6,
"lastUsedTimestamp": 1791227118678
},
"c:\\program files\\powershell\\7\\pwsh.exe": {
"name": "PowerShell 7",
"path": "c:\\program files\\powershell\\7\\pwsh.exe",
"launchCount": 0,
"focusCount": 1,
"activeDurationSeconds": 3,
"lastUsedTimestamp": 1791092072540
}, },
"c:\\portableapps\\freecad\\bin\\freecad.exe": { "c:\\portableapps\\freecad\\bin\\freecad.exe": {
"name": "freecad", "name": "freecad",
"path": "c:\\portableapps\\freecad\\bin\\freecad.exe", "path": "c:\\portableapps\\freecad\\bin\\freecad.exe",
"launchCount": 3, "launchCount": 5,
"focusCount": 17, "focusCount": 12,
"activeDurationSeconds": 4871, "activeDurationSeconds": 567,
"lastUsedTimestamp": 1788923536820 "lastUsedTimestamp": 1791164538716
}, },
"c:\\portableapps\\irfanview\\app\\irfanview64\\i_view64.exe": { "c:\\program files\\nvidia corporation\\nvidia app\\cef\\nvidia app.exe": {
"name": "IrfanView 64-bit", "name": "NVIDIA App",
"path": "c:\\portableapps\\irfanview\\app\\irfanview64\\i_view64.exe", "path": "c:\\program files\\nvidia corporation\\nvidia app\\cef\\nvidia app.exe",
"launchCount": 3, "launchCount": 1,
"focusCount": 4,
"activeDurationSeconds": 34,
"lastUsedTimestamp": 1791163077450
},
"c:\\program files\\git\\cmd\\git.exe": {
"name": "Git for Windows",
"path": "c:\\program files\\git\\cmd\\git.exe",
"launchCount": 15,
"focusCount": 14,
"activeDurationSeconds": 15,
"lastUsedTimestamp": 1791229434986
},
"c:\\users\\ryan\\.codex\\packages\\app-server-daemon\\releases\\0.157.1-x86_64-pc-windows-msvc\\codex-path\\rg.exe": {
"name": "rg",
"path": "c:\\users\\ryan\\.codex\\packages\\app-server-daemon\\releases\\0.157.1-x86_64-pc-windows-msvc\\codex-path\\rg.exe",
"launchCount": 1,
"focusCount": 1, "focusCount": 1,
"activeDurationSeconds": 95, "activeDurationSeconds": 1,
"lastUsedTimestamp": 1788586171205 "lastUsedTimestamp": 1791229405819
}, },
"h:\\steam\\steamapps\\common\\content warning\\content warning.exe": { "c:\\program files\\windowsapps\\canva.affinity_3.0.3.4027_x64__8a0j1tnjnt4a4\\app\\affinity.exe": {
"name": "content warning", "name": "Affinity",
"path": "h:\\steam\\steamapps\\common\\content warning\\content warning.exe", "path": "c:\\program files\\windowsapps\\canva.affinity_3.0.3.4027_x64__8a0j1tnjnt4a4\\app\\affinity.exe",
"launchCount": 1,
"focusCount": 30,
"activeDurationSeconds": 3249,
"lastUsedTimestamp": 1791674556686
},
"c:\\program files\\tailscale\\tailscale-ipn.exe": {
"name": "Tailscale GUI client",
"path": "c:\\program files\\tailscale\\tailscale-ipn.exe",
"launchCount": 2, "launchCount": 2,
"focusCount": 10, "focusCount": 6,
"activeDurationSeconds": 3812, "activeDurationSeconds": 355,
"lastUsedTimestamp": 1788754135308 "lastUsedTimestamp": 1791691505062
},
"c:\\program files\\nomachine\\bin\\nxrunner.bin": {
"name": "NoMachine Tray Monitor",
"path": "c:\\program files\\nomachine\\bin\\nxrunner.bin",
"launchCount": 1,
"focusCount": 2,
"activeDurationSeconds": 3,
"lastUsedTimestamp": 1791382888458
}, },
"c:\\program files\\7-zip\\7zfm.exe": { "c:\\program files\\7-zip\\7zfm.exe": {
"name": "7-Zip File Manager", "name": "7-Zip File Manager",
"path": "c:\\program files\\7-zip\\7zfm.exe", "path": "c:\\program files\\7-zip\\7zfm.exe",
"launchCount": 1, "launchCount": 1,
"focusCount": 3, "focusCount": 9,
"activeDurationSeconds": 35, "activeDurationSeconds": 20,
"lastUsedTimestamp": 1788751440759 "lastUsedTimestamp": 1791434432754
}, },
"c:\\program files\\cheat engine 7.5\\cheatengine-x86_64-sse4-avx2.exe": { "c:\\program files\\internet explorer\\iexplore.exe": {
"name": "Cheat Engine", "name": "Internet Explorer",
"path": "c:\\program files\\cheat engine 7.5\\cheatengine-x86_64-sse4-avx2.exe", "path": "c:\\program files\\internet explorer\\iexplore.exe",
"launchCount": 11,
"focusCount": 10,
"activeDurationSeconds": 84,
"lastUsedTimestamp": 1791520033017
},
"c:\\portableapps\\irfanview\\app\\irfanview64\\i_view64.exe": {
"name": "IrfanView 64-bit",
"path": "c:\\portableapps\\irfanview\\app\\irfanview64\\i_view64.exe",
"launchCount": 7,
"focusCount": 6,
"activeDurationSeconds": 193,
"lastUsedTimestamp": 1791603651815
},
"c:\\users\\ryan\\appdata\\roaming\\spotify\\spotify.exe": {
"name": "Spotify",
"path": "c:\\users\\ryan\\appdata\\roaming\\spotify\\spotify.exe",
"launchCount": 1, "launchCount": 1,
"focusCount": 7, "focusCount": 4,
"activeDurationSeconds": 32, "activeDurationSeconds": 227,
"lastUsedTimestamp": 1788754937452 "lastUsedTimestamp": 1791666292289
}, },
"c:\\program files (x86)\\steam\\steam.exe": { "c:\\portableapps\\gimpportable\\gimpportable.exe": {
"name": "Steam", "name": "GIMP Portable (PortableApps.com Launcher)",
"path": "c:\\program files (x86)\\steam\\steam.exe", "path": "c:\\portableapps\\gimpportable\\gimpportable.exe",
"launchCount": 1, "launchCount": 1,
"focusCount": 1, "focusCount": 1,
"activeDurationSeconds": 174, "activeDurationSeconds": 2,
"lastUsedTimestamp": 1788838072451 "lastUsedTimestamp": 1791604589829
}, },
"h:\\steam\\steamapps\\common\\peak\\peak.exe": { "c:\\portableapps\\gimpportable\\app\\gimp\\bin\\gimp-2.10.exe": {
"name": "peak", "name": "GNU Image Manipulation Program",
"path": "h:\\steam\\steamapps\\common\\peak\\peak.exe", "path": "c:\\portableapps\\gimpportable\\app\\gimp\\bin\\gimp-2.10.exe",
"launchCount": 1,
"focusCount": 13,
"activeDurationSeconds": 1473,
"lastUsedTimestamp": 1791683169760
},
"c:\\portableapps\\gimpportable\\app\\gimp\\lib\\gimp\\2.0\\plug-ins\\file-png\\file-png.exe": {
"name": "GNU Image Manipulation Program Plug-In",
"path": "c:\\portableapps\\gimpportable\\app\\gimp\\lib\\gimp\\2.0\\plug-ins\\file-png\\file-png.exe",
"launchCount": 1, "launchCount": 1,
"focusCount": 1, "focusCount": 1,
"activeDurationSeconds": 22, "activeDurationSeconds": 1,
"lastUsedTimestamp": 1788838292184 "lastUsedTimestamp": 1791605126035
}, },
"d:\\python utilities\\icue\\app\\dist\\icue assigner\\icue assigner.exe": { "c:\\program files\\mythicsoft\\agent ransack\\agentransack.exe": {
"name": "icue assigner", "name": "Agent Ransack",
"path": "d:\\python utilities\\icue\\app\\dist\\icue assigner\\icue assigner.exe", "path": "c:\\program files\\mythicsoft\\agent ransack\\agentransack.exe",
"launchCount": 1, "launchCount": 1,
"focusCount": 1, "focusCount": 6,
"activeDurationSeconds": 8, "activeDurationSeconds": 291,
"lastUsedTimestamp": 1788923506351 "lastUsedTimestamp": 1791737327579
}, },
"c:\\portableapps\\dimmer\\dimmer.exe": { "c:\\program files (x86)\\windows media player\\wmplayer.exe": {
"name": "Dimmer - Brightness control software", "name": "Windows Media Player",
"path": "c:\\portableapps\\dimmer\\dimmer.exe", "path": "c:\\program files (x86)\\windows media player\\wmplayer.exe",
"launchCount": 1, "launchCount": 3,
"focusCount": 1, "focusCount": 2,
"activeDurationSeconds": 6, "activeDurationSeconds": 69,
"lastUsedTimestamp": 1788924847522 "lastUsedTimestamp": 1791672161738
} }
} }
+31 -11
View File
@@ -8,6 +8,33 @@ import streamDeck from "@elgato/streamdeck";
const execFileAsync = promisify(execFile); const execFileAsync = promisify(execFile);
async function launchOutsidePluginJob(commandLine: string, currentDirectory: string): Promise<void> {
// Stream Deck can place its plugin process tree in a Windows job object. Node's
// `detached` option only detaches the console, so ask the WMI service to create
// the app process instead; Win32_Process.Create does not inherit that job.
const encodedCommandLine = Buffer.from(commandLine, "utf16le").toString("base64");
const encodedCurrentDirectory = Buffer.from(currentDirectory, "utf16le").toString("base64");
const script = `
$commandLine = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('${encodedCommandLine}'))
$currentDirectory = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('${encodedCurrentDirectory}'))
$result = Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = $commandLine
CurrentDirectory = $currentDirectory
}
if ($result.ReturnValue -ne 0) {
throw "Win32_Process.Create failed with code $($result.ReturnValue)"
}
`;
const encodedScript = Buffer.from(script, "utf16le").toString("base64");
await execFileAsync("powershell.exe", [
"-NoProfile",
"-NonInteractive",
"-EncodedCommand",
encodedScript
], { windowsHide: true, timeout: 15000 });
}
export interface InstalledApp { export interface InstalledApp {
name: string; name: string;
path: string; path: string;
@@ -311,18 +338,11 @@ static async activateOrLaunchApp(targetPath: string, bringToFront = true): Promi
if (!activated) { if (!activated) {
if (isUrlShortcut) { if (isUrlShortcut) {
logger.info(`[AppLauncher] Launching URL shortcut at path "${cleanPath}"`); logger.info(`[AppLauncher] Launching URL shortcut at path "${cleanPath}"`);
execFile("cmd.exe", ["/c", "start", "", cleanPath], (err: Error | null) => { const explorerPath = path.join(process.env.WINDIR || "C:\\Windows", "explorer.exe");
if (err) { await launchOutsidePluginJob(`"${explorerPath}" "${cleanPath}"`, path.dirname(cleanPath));
streamDeck.logger.error(`[AppLauncher] Failed to launch URL shortcut at path "${cleanPath}":`, err);
}
});
} else { } else {
logger.info(`[AppLauncher] Launching executable at path "${cleanPath}"`); logger.info(`[AppLauncher] Launching executable at path "${cleanPath}"`);
execFile(cleanPath, (err: Error | null) => { await launchOutsidePluginJob(`"${cleanPath}"`, path.dirname(cleanPath));
if (err) {
streamDeck.logger.error(`[AppLauncher] Failed to launch executable at path "${cleanPath}":`, err);
}
});
} }
} }
} }
@@ -671,4 +691,4 @@ public static async getInstalledApps(): Promise<InstalledApp[]> {
return null; return null;
} }
} }