Skip to content

Commit f1e6bff

Browse files
committed
fix(window): track child processes spawned from launched apps.
Some apps spwan child processes os we need to track their PID to be able to attach to the correct window
1 parent a7ce03f commit f1e6bff

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

lib/commands/app.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,31 @@ export async function setWindowRect(
276276

277277

278278
export async function attachToApplicationWindow(this: NovaWindowsDriver, processIds: number[]): Promise<void> {
279-
this.log.debug(`Attaching to application window. Process IDs: [${processIds.join(', ')}]`);
279+
const trackedPids = new Set<number>(processIds);
280+
this.log.debug(`Attaching to application window. Process IDs: [${[...trackedPids].join(', ')}]`);
280281
const timeout = (this.caps['ms:waitForAppLaunch'] ?? 0) * 1000 || SLEEP_INTERVAL_MS * 20;
281282
const start = Date.now();
282283
let attempts = 0;
283284

284285
while (Date.now() - start < timeout) {
285-
const handles = getWindowAllHandlesForProcessIds(processIds);
286+
// Discover child processes of all currently-tracked PIDs
287+
const pidList = [...trackedPids].join(', ');
288+
const childPidResult = await this.sendPowerShellCommand(
289+
/* ps1 */ `@(Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -in @(${pidList}) }).ProcessId`
290+
);
291+
for (const token of childPidResult.split('\n').map((s) => s.trim()).filter(Boolean)) {
292+
const childPid = Number(token);
293+
if (!isNaN(childPid) && childPid > 0 && !trackedPids.has(childPid)) {
294+
this.log.debug(`Discovered child process PID ${childPid} spawned by tracked PIDs`);
295+
trackedPids.add(childPid);
296+
}
297+
}
298+
299+
const currentPids = [...trackedPids];
300+
const handles = getWindowAllHandlesForProcessIds(currentPids);
286301

287302
if (handles.length > 0) {
288-
this.log.debug(`Found ${handles.length} window handle(s) for PIDs [${processIds.join(', ')}]: ${handles.map((h) => `0x${h.toString(16).padStart(8, '0')}`).join(', ')}`);
303+
this.log.debug(`Found ${handles.length} window handle(s) for PIDs [${currentPids.join(', ')}]: ${handles.map((h) => `0x${h.toString(16).padStart(8, '0')}`).join(', ')}`);
289304

290305
for (const handle of handles) {
291306
const elementId = await this.sendPowerShellCommand(AutomationElement.rootElement.findFirst(TreeScope.CHILDREN, new PropertyCondition(Property.NATIVE_WINDOW_HANDLE, new PSInt32(handle))).buildCommand());
@@ -295,6 +310,7 @@ export async function attachToApplicationWindow(this: NovaWindowsDriver, process
295310
if ((await this.sendPowerShellCommand(/* ps1 */ `$null -ne $rootElement`)).toLowerCase() === 'true') {
296311
const confirmedHandle = Number(await this.sendPowerShellCommand(AutomationElement.automationRoot.buildGetPropertyCommand(Property.NATIVE_WINDOW_HANDLE)));
297312
this.log.info(`Successfully attached to window. Native window handle: 0x${confirmedHandle.toString(16).padStart(8, '0')}`);
313+
this.appProcessIds = currentPids;
298314
if (!trySetForegroundWindow(confirmedHandle)) {
299315
await this.focusElement({
300316
[W3C_ELEMENT_KEY]: elementId,

0 commit comments

Comments
 (0)