Skip to content

Commit 7d22b8a

Browse files
committed
fix(windows): silent NSIS PowerShell via nsExec and shell taskbar icon
Replace ExecWait with nsExec::Exec for hsp-app-process.ps1 so powershell.exe does not attach a flashing console. On packaged Windows, apply app.getFileIcon (large) to the main BrowserWindow so the taskbar gets a real icon when createFromPath on the exe is empty. Made-with: Cursor
1 parent ea20356 commit 7d22b8a

3 files changed

Lines changed: 39 additions & 5 deletions

File tree

app/windows/build.cjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,32 @@ function createWindow() {
18161816
show: false,
18171817
});
18181818

1819+
// Windows: nativeImage.createFromPath(.exe) often returns an empty image; shell-extracted icons work for the taskbar.
1820+
if (process.platform === "win32" && app.isPackaged) {
1821+
const iconPaths = [resolveAppIconIcoPath(), process.execPath].filter(
1822+
(p) => p && (p === process.execPath || fs.existsSync(p)),
1823+
);
1824+
void (async () => {
1825+
for (const p of iconPaths) {
1826+
try {
1827+
const img = await app.getFileIcon(p, { size: "large" });
1828+
if (mainWindow.isDestroyed()) return;
1829+
if (!img.isEmpty()) {
1830+
mainWindow.setIcon(img);
1831+
return;
1832+
}
1833+
} catch (e) {
1834+
try {
1835+
log(`getFileIcon(${p}): ${e?.message || e}`);
1836+
} catch (_) {}
1837+
}
1838+
}
1839+
try {
1840+
log("warn: taskbar icon: getFileIcon found no usable image");
1841+
} catch (_) {}
1842+
})();
1843+
}
1844+
18191845
mainWindow.once("ready-to-show", () => {
18201846
// Fill the display work area by default (fresh install, after update, new window).
18211847
try {

app/windows/hsp-app-process.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Used by installer-hooks.nsi (ExecWait -File). Sync process names with package.json:
1+
# Used by installer-hooks.nsi (nsExec::Exec, no console). Sync process names with package.json:
22
# build.productName, name (npm), product-brand portable slug, legacy "Hyperlinks Space App".
33
param(
44
[Parameter(Mandatory = $true)]

app/windows/installer-hooks.nsi

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,23 @@ Function HspClearEnvInstDir
131131
System::Call 'kernel32::SetEnvironmentVariable(t, i) ("HSP_INSTDIR", 0)'
132132
FunctionEnd
133133

134-
; PowerShell: -WindowStyle Hidden avoids flashing console windows (ExecWait still waits for exit).
134+
; PowerShell: use nsExec::Exec (not ExecWait). ExecWait always attaches a console to powershell.exe,
135+
; which flashes on screen even with -WindowStyle Hidden; nsExec runs the process with no console window.
135136
Function HspAnyPackagedExeRunning
136137
Call HspResolvePowerShellExe
137138
Call HspSetEnvInstDir
138139
IfFileExists "$PLUGINSDIR\hsp-app-process.ps1" 0 hspAnyExeNoScript
139-
ExecWait '"$R5" -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File "$PLUGINSDIR\hsp-app-process.ps1" -Action Test' $R4
140+
nsExec::Exec `"$R5" -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$PLUGINSDIR\hsp-app-process.ps1" -Action Test`
141+
Pop $R4
140142
Call HspClearEnvInstDir
143+
StrCmp $R4 "error" hspAnyExeNsFail
144+
StrCmp $R4 "timeout" hspAnyExeNsFail
141145
IntCmp $R4 0 hspAnyExeYes
142146
StrCpy $0 0
143147
Return
148+
hspAnyExeNsFail:
149+
StrCpy $0 0
150+
Return
144151
hspAnyExeNoScript:
145152
Call HspClearEnvInstDir
146153
StrCpy $0 0
@@ -168,7 +175,8 @@ Function HspKillPackagedAppProcesses
168175
Call HspResolvePowerShellExe
169176
Call HspSetEnvInstDir
170177
IfFileExists "$PLUGINSDIR\hsp-app-process.ps1" 0 hspKillNoScript
171-
ExecWait '"$R5" -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File "$PLUGINSDIR\hsp-app-process.ps1" -Action Kill' $R4
178+
nsExec::Exec `"$R5" -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$PLUGINSDIR\hsp-app-process.ps1" -Action Kill`
179+
Pop $R4
172180
hspKillNoScript:
173181
Call HspClearEnvInstDir
174182
FunctionEnd
@@ -319,7 +327,7 @@ hspCustomInstallAfterLaunch:
319327
!insertmacro HspAppendInstallerLog "[uninstaller] complete"
320328
!macroend
321329

322-
; Runs before Section install (electron-builder prepends this include). Drops helper script for ExecWait -File.
330+
; Runs before Section install (electron-builder prepends this include). Drops helper script for nsExec::Exec -File.
323331
; Use BUILD_RESOURCES_DIR so makensis finds the script when cwd is the NSIS cache dir (Forge/CI).
324332
!ifndef BUILD_UNINSTALLER
325333
Section "-hsp_app_process_ps1"

0 commit comments

Comments
 (0)