vitaly-t
vitaly-t

Reputation: 25900

Bring Node.js console window to the front

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

Answers (2)

Estradiaz
Estradiaz

Reputation: 3573

TL;DR; bringToFront


Use Node.js N-API

The basic idea is to use the windows api to controll the window states.

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

Laurent Dhont
Laurent Dhont

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

Related Questions