mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 00:02:10 +00:00
* fix(windows): ship the process-table addon to the relocated daemon host The Windows terminal daemon runs from a copy of the app under %LOCALAPPDATA%\Orca\daemon-host\<version>. That copy took node-pty but not @vscode/windows-process-tree, so the daemon's bare require of the addon found nothing and every process-table read (foreground tracking, descendant sweeps) fell back to a powershell.exe Get-CimInstance scan (#16905). - Copy the addon's runtime files (package.json, lib/, the .node binary) into the host; the ~25MB of gyp intermediates beside them are filtered out. - Treat a host missing those files as unmaterialized, so hosts built before this are rebuilt, and skip relocation if the install itself lacks them. - Log the daemon's native/CIM capability at startup and warn once when the process table falls back to CIM. Revives #19525 on current main. * test(windows): locate update-survival loss before relaunch * test(windows): preserve daemon tree before update-survival proof * test(windows): distinguish Electron exit from launcher close timeout * test(windows): verify process exit when inherited pipes delay close * test(windows): trace installer process checks in isolated survival runs * fix(windows): probe process-query capability before installer sweep * fix(windows): match installer probe and process-check profile behavior * fix(windows): use NSIS separators for the process-check include * test(windows): dismiss session-search overlay in survival harness --------- Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
import { readFileSync, writeFileSync } from 'node:fs'
|
|
import { createRequire } from 'node:module'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const require = createRequire(import.meta.url)
|
|
const builderRequire = createRequire(require.resolve('electron-builder/package.json'))
|
|
const builderRoot = path.dirname(builderRequire.resolve('app-builder-lib/package.json'))
|
|
const processChecks = path.join(
|
|
builderRoot,
|
|
'templates/nsis/include/allowOnlyOneInstallerInstance.nsh'
|
|
)
|
|
const hooks = fileURLToPath(
|
|
new URL('../../../config/nsis/orca-installer-hooks.nsh', import.meta.url)
|
|
)
|
|
const capabilityCheck = fileURLToPath(
|
|
new URL('../../../config/nsis/orca-process-check.nsh', import.meta.url)
|
|
)
|
|
|
|
// CI-only patch: the installer and its embedded uninstaller share these macros.
|
|
const traceMacro = `
|
|
!macro ORCA_E2E_TRACE TEXT
|
|
Push $R8
|
|
Push $R9
|
|
StrCpy $R8 0
|
|
\${if} \${Errors}
|
|
StrCpy $R8 1
|
|
\${endIf}
|
|
ClearErrors
|
|
ReadEnvStr $R9 ORCA_E2E_NSIS_TRACE
|
|
\${if} $R9 != ""
|
|
FileOpen $R9 "$R9" a
|
|
\${ifNot} \${Errors}
|
|
FileSeek $R9 0 END
|
|
FileWrite $R9 "$EXEPATH | $CMDLINE | dir=$INSTDIR | \${TEXT}$\\r$\\n"
|
|
FileClose $R9
|
|
\${endIf}
|
|
\${endIf}
|
|
ClearErrors
|
|
\${if} $R8 == 1
|
|
SetErrors
|
|
\${endIf}
|
|
Pop $R9
|
|
Pop $R8
|
|
!macroend
|
|
`
|
|
|
|
function replaceOnce(source, anchor, replacement) {
|
|
if (source.split(anchor).length !== 2) {
|
|
throw new Error(`Expected one NSIS trace anchor: ${anchor}`)
|
|
}
|
|
return source.replace(anchor, () => replacement)
|
|
}
|
|
|
|
function insertAfter(source, anchor, insertion) {
|
|
return replaceOnce(source, anchor, `${anchor}\n${insertion}`)
|
|
}
|
|
|
|
let checks = readFileSync(processChecks, 'utf8').replaceAll('\r\n', '\n')
|
|
checks = traceMacro + checks
|
|
checks = insertAfter(
|
|
checks,
|
|
'!macro FIND_PROCESS _FILE _RETURN',
|
|
' !insertmacro ORCA_E2E_TRACE "find image=${_FILE} branch=$IsPowerShellAvailable"'
|
|
)
|
|
checks = insertAfter(
|
|
checks,
|
|
'!macro KILL_PROCESS _FILE _FORCE',
|
|
' !insertmacro ORCA_E2E_TRACE "kill image=${_FILE} force=${_FORCE} branch=$IsPowerShellAvailable"'
|
|
)
|
|
checks = replaceOnce(
|
|
checks,
|
|
' Pop $0\n!macroend ',
|
|
' Pop $0\n !insertmacro ORCA_E2E_TRACE "kill-result=$0"\n!macroend '
|
|
)
|
|
const findCall = '!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0'
|
|
if (checks.split(findCall).length !== 4) {
|
|
throw new Error('Expected three find-process calls')
|
|
}
|
|
checks = checks.replaceAll(
|
|
findCall,
|
|
() => `${findCall}\n !insertmacro ORCA_E2E_TRACE "find-result=$R0"`
|
|
)
|
|
let uninstall = readFileSync(hooks, 'utf8').replaceAll('\r\n', '\n')
|
|
uninstall = insertAfter(
|
|
uninstall,
|
|
'!macro customUnInstall',
|
|
' !insertmacro ORCA_E2E_TRACE "custom-uninstall entered"'
|
|
)
|
|
uninstall = insertAfter(
|
|
uninstall,
|
|
' ${ifNot} ${isUpdated}',
|
|
' !insertmacro ORCA_E2E_TRACE "genuine-uninstall daemon sweep"'
|
|
)
|
|
let capability = readFileSync(capabilityCheck, 'utf8').replaceAll('\r\n', '\n')
|
|
capability = insertAfter(
|
|
capability,
|
|
' Pop $0',
|
|
' !insertmacro ORCA_E2E_TRACE "capability=$0 powershell=$PowerShellPath"'
|
|
)
|
|
capability = replaceOnce(
|
|
capability,
|
|
' !insertmacro _CHECK_APP_RUNNING',
|
|
' !insertmacro ORCA_E2E_TRACE "selected-branch=$IsPowerShellAvailable (0=path,1=image)"\n !insertmacro _CHECK_APP_RUNNING'
|
|
)
|
|
|
|
if (!process.argv.includes('--check')) {
|
|
if (process.env.GITHUB_ACTIONS !== 'true' || process.platform !== 'win32') {
|
|
throw new Error('Installer tracing may only patch a disposable Windows CI checkout')
|
|
}
|
|
writeFileSync(processChecks, checks)
|
|
writeFileSync(hooks, uninstall)
|
|
writeFileSync(capabilityCheck, capability)
|
|
}
|
|
console.log('Validated installer/uninstaller branch-trace anchors')
|