I want to changes the parent window of the specified child window by calling native modules in NodeJS16.(electron 22.)
CPP code:
#include <napi.h>
#include <windows.h>
#include <winuser.h>
using namespace Napi;
class ContextData
{
private:
HWND hWnd_;
LPDWORD lpdwProcessId_;
Function &cb_;
public:
ContextData(Function &cb, HWND hWnd, LPDWORD lpdwProcessId) : cb_(cb), hWnd_(hWnd), lpdwProcessId_(lpdwProcessId) {}
HWND hWnd()
{
return hWnd_;
}
LPDWORD lpdwProcessId()
{
return lpdwProcessId_;
}
Function &cb()
{
return cb_;
}
static BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM callbackLParam)
{
ContextData *lParam = (ContextData *)callbackLParam;
LPDWORD pid;
GetWindowThreadProcessId(hWnd, (LPDWORD)pid);
uint32_t childWindowPid = *(uint32_t *)pid;
printf("childWindowPid is: %d\n", childWindowPid);
uint32_t targetWindowPid = *(uint32_t *)(lParam->lpdwProcessId());
printf("targetWindowPid is: %d\n", targetWindowPid);
if (childWindowPid == targetWindowPid)
{
printf("find successfully\n");
SetParent(hWnd, lParam->hWnd());
(lParam->cb()).Call({});
return FALSE;
}
return TRUE;
}
};
static void Method(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return;
}
if (!info[0].IsBuffer())
{
TypeError::New(env, "hwnd must be buffer")
.ThrowAsJavaScriptException();
return;
}
if (!info[1].IsNumber())
{
TypeError::New(env, "pid must be number")
.ThrowAsJavaScriptException();
return;
}
if (!info[2].IsFunction())
{
TypeError::New(env, "cb must be function")
.ThrowAsJavaScriptException();
return;
}
// parent window's hWnd
Buffer<void *> handle = info[0].As<Buffer<void *>>();
HWND hWnd = static_cast<HWND>(*reinterpret_cast<void **>(handle.Data()));
// child process identifier
uint32_t pid = info[1].As<Number>().Uint32Value();
LPDWORD lpdwProcessId = reinterpret_cast<LPDWORD>(&pid);
// callback
Function cb = info[2].As<Function>();
ContextData context(cb, hWnd, lpdwProcessId);
EnumChildWindows(hWnd, ContextData::EnumChildProc, (LPARAM)(&context));
return;
}
Object Init(Env env, Object exports)
{
exports.Set(String::New(env, "SetParentNapi"),
Function::New(env, Method));
return exports;
}
NODE_API_MODULE(addon, Init)
JS code:
const controller = new AbortController()
try {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for await (const _value of setInterval(5000, undefined, {
signal: controller.signal,
})) {
SetParentNapi(buffer, pid, () => {
log4js.info('SetParent success!')
controller.abort()
})
}
} catch (error) {
if (controller.signal.aborted) {
log4js.debug('timeout aborted!')
return
}
log4js.error(error)
}
If SetParentNapi
executes ok, it would print out message like following:
childWindowPid is: 6872
targetWindowPid is: 8324
childWindowPid is: 8324
targetWindowPid is: 8324
find successfully
Every seems ok, but if I try to comment out the following code in JS,
controller.abort()
to force calling native modules repeatedly, the app crash.
[20464:1231/223445.713:ERROR:crashpad_client_win.cc(844)] not connected
Process finished with exit code -36861
Why it happened, how can I fix it?