You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS环境下用JS获取Windows应用NativeWindowHandle方法求助

如何在Node.js中通过PID获取Windows应用的NativeWindowHandle?

可以通过两种方式实现:调用PowerShell脚本借助.NET API,或者使用Node.js原生绑定库直接调用Windows系统API,以下是具体方案:


方案一:PowerShell脚本(无额外依赖,快速实现)

利用PowerShell可以直接调用Windows User32 API的特性,编写脚本根据PID枚举窗口并返回句柄,再在Node.js中执行该脚本。

Node.js调用代码

const { exec } = require('child_process');

function getNativeWindowHandle(pid, callback) {
    // 嵌入PowerShell脚本逻辑
    const psScript = `
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WindowFinder {
    [DllImport("user32.dll")]
    public static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
    [DllImport("user32.dll")]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
    public static IntPtr FindWindowByProcessId(uint pid) {
        IntPtr found = IntPtr.Zero;
        EnumWindows((hWnd, lParam) => {
            uint currentPid;
            GetWindowThreadProcessId(hWnd, out currentPid);
            if (currentPid == pid) {
                found = hWnd;
                return false;
            }
            return true;
        }, IntPtr.Zero);
        return found;
    }
}
"@
$handle = [WindowFinder]::FindWindowByProcessId(${pid})
if ($handle -ne [IntPtr]::Zero) {
    $handle.ToString("X")
} else {
    ""
}
    `;

    exec(`powershell -Command "${psScript}"`, (err, stdout, stderr) => {
        if (err) {
            callback(err, null);
            return;
        }
        const handle = stdout.trim();
        callback(null, handle ? `0x${handle}` : null);
    });
}

// 使用示例:替换为目标应用的实际PID
const targetPid = 12345;
getNativeWindowHandle(targetPid, (err, handle) => {
    if (err) {
        console.error('获取窗口句柄失败:', err);
        return;
    }
    handle ? console.log('NativeWindowHandle:', handle) : console.log('未找到对应PID的窗口');
});

方案二:Node.js原生绑定库(直接调用系统API)

使用ffi-napi和ref-napi库直接在Node.js中调用Windows User32.dll的API,无需依赖PowerShell。

步骤1:安装依赖

npm install ffi-napi ref-napi

步骤2:编写代码

const ffi = require('ffi-napi');
const ref = require('ref-napi');

// 定义User32.dll的API接口
const user32 = ffi.Library('user32.dll', {
    'EnumWindows': ['bool', ['pointer', 'int32']],
    'GetWindowThreadProcessId': ['uint32', ['pointer', 'pointer']]
});

// 定义枚举窗口的回调函数类型
const EnumWindowsProc = ffi.Callback('bool', ['pointer', 'int32'], (hWnd, lParam) => {
    const pidPtr = ref.alloc('uint32');
    user32.GetWindowThreadProcessId(hWnd, pidPtr);
    const currentPid = ref.deref(pidPtr);
    const targetPid = ref.deref(ref.cast(lParam, ref.refType('uint32')));
    
    if (currentPid === targetPid) {
        // 将找到的窗口句柄写入内存指针
        const handlePtr = ref.cast(lParam, ref.refType('pointer'));
        handlePtr.writePointer(hWnd);
        return false; // 停止枚举
    }
    return true; // 继续枚举
});

function getNativeWindowHandle(pid) {
    return new Promise((resolve, reject) => {
        const resultPtr = ref.alloc('pointer');
        const pidPtr = ref.alloc('uint32', pid);
        
        const success = user32.EnumWindows(EnumWindowsProc, ref.address(pidPtr));
        if (!success) {
            reject(new Error('枚举窗口失败'));
            return;
        }
        
        const hWnd = resultPtr.readPointer();
        if (hWnd.isNull()) {
            resolve(null);
        } else {
            // 转换为Inspect.exe一致的十六进制格式
            const handleHex = `0x${hWnd.readUInt32LE().toString(16).toUpperCase()}`;
            resolve(handleHex);
        }
    });
}

// 使用示例
(async () => {
    const targetPid = 12345; // 替换为目标应用的实际PID
    try {
        const handle = await getNativeWindowHandle(targetPid);
        handle ? console.log('NativeWindowHandle:', handle) : console.log('未找到对应PID的窗口');
    } catch (err) {
        console.error('获取窗口句柄失败:', err);
    }
})();

注意事项

  • 一个PID可能对应多个窗口(如应用弹窗),上述代码默认返回第一个匹配的窗口句柄,可修改逻辑收集所有匹配句柄。
  • 若目标应用以管理员权限运行,Node.js进程也需以管理员权限启动才能访问窗口句柄。
  • 方案二需配置Node.js编译环境(如Windows下的Visual Studio Build Tools),环境配置复杂时优先选方案一。

内容的提问来源于stack exchange,提问作者lakers5824

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:10:32