Reputation: 25900
When running a Node.js app in a console, is there a way to bring the console window to the front programmatically, from within the app itself?
I am primarily interested in doing so in Windows, using the latest Node.js (v13 atm)
And if there is a package that can do so, that would be good enough.
Scenario
Running multiple Node.js consoles. When something important happens in one of them, bring the window up front. I haven't been able to find any library or example for it.
Upvotes: 3
Views: 1544
Reputation: 3573
TL;DR; bringToFront
One can use SetForegroundWindow
.
But there are some restrictions:
- The process is the foreground process.
- The process was started by the foreground process.
- The process received the last input event.
- There is no foreground process.
- The foreground process is being debugged.
- The foreground is not locked (see LockSetForegroundWindow).
- The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
- No menus are active.
To workaround those restrictions one can programatically simulate userinput:
press alt key (think of e.g.: alt+tab
):
keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
now bring to front
SetForegroundWindow(hWnd);
release key
keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
copy of main logic for stackoverflow:
#include "./pidToFront.h"
#include <windows.h>
using namespace v8;
void SetForegroundWindowInternal(HWND hWnd)
{
if(!::IsWindow(hWnd)) return;
BYTE keyState[256] = {0};
//to unlock SetForegroundWindow we need to imitate Alt pressing
if(::GetKeyboardState((LPBYTE)&keyState))
{
if(!(keyState[VK_MENU] & 0x80))
{
::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
}
}
::SetForegroundWindow(hWnd);
if(::GetKeyboardState((LPBYTE)&keyState))
if(::GetKeyboardState((LPBYTE)&keyState))
if(::GetKeyboardState((LPBYTE)&keyState))
{
if(!(keyState[VK_MENU] & 0x80))
{
::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}
}
HWND g_HWND=NULL;
BOOL CALLBACK EnumWindowsProcMy(HWND hwnd,LPARAM lParam)
{
DWORD lpdwProcessId;
GetWindowThreadProcessId(hwnd,&lpdwProcessId);
if(lpdwProcessId==lParam)
{
g_HWND=hwnd;
return FALSE;
}
return TRUE;
}
void win32js::toFront(const Nan::FunctionCallbackInfo<Value>& info){
Local<Context> context = info.GetIsolate()->GetCurrentContext();
if(info.Length() < 1 || !info[0]->IsNumber()){
Nan::ThrowTypeError("Invalid argument expected pid as number");
}
LPARAM pid = info[0]->NumberValue(context).FromJust();
if(EnumWindows(EnumWindowsProcMy, (double)pid)){
info.GetReturnValue().Set(-2);
}
if(g_HWND > 0){
SetForegroundWindow(g_HWND);
if(GetForegroundWindow() == g_HWND){
info.GetReturnValue().Set((double)(unsigned long)g_HWND);
g_HWND = NULL;
return;
}
SetForegroundWindowInternal(g_HWND);
if(GetForegroundWindow() == g_HWND){
info.GetReturnValue().Set((double)(unsigned long)g_HWND);
g_HWND = NULL;
return;
}
} else {
info.GetReturnValue().Set(-1);
}
}
Upvotes: 6
Reputation: 1062
I am not sure this the answer to your question but it looks like this could resolve your problem: Setting focus to a Windows application from Node-JS
Sorry if this is wrong.
Upvotes: 1