【问题标题】:Bring Node.js console window to the front将 Node.js 控制台窗口置于最前面
【发布时间】:2019-11-21 03:07:36
【问题描述】:

在控制台中运行 Node.js 应用程序时,有没有办法以编程方式从应用程序本身将控制台窗口置于最前面?

我主要感兴趣的是在 Windows 中使用最新的 Node.js (v13 atm)

如果有一个包可以做到这一点,那就足够了。

场景

运行多个 Node.js 控制台。当其中一个发生重要事情时,请将窗户放在前面。我找不到任何库或示例。

【问题讨论】:

  • node.js 中没有类似的东西。您必须找到在 Windows 上执行此操作的本机代码模块。我不知道有一个。
  • 是的,使用批处理脚本,您可以查看此答案以获取灵感stackoverflow.com/questions/557166/…

标签: node.js


【解决方案1】:

TL;DR; bringToFront


使用 Node.js N-API

基本思路是使用windows api来控制窗口状态。

可以使用SetForegroundWindow

但是有一些restrictions:

  • 该进程是前台进程。
  • 进程由前台进程启动。
  • 进程收到最后一个输入事件。
  • 没有前台进程。
  • 正在调试前台进程。
  • 前景未锁定(请参阅 LockSetForegroundWindow)。
  • 前台锁定超时已过期(请参阅 SystemParametersInfo 中的 SPI_GETFOREGROUNDLOCKTIMEOUT)。
  • 没有处于活动状态的菜单。

要解决这些限制,可以通过编程方式模拟用户输入:

  • 按 alt 键(想想例如:alt+tab):

  • keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);

  • 现在放在前面

  • SetForegroundWindow(hWnd);

  • 释放键

  • keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);


堆栈的主逻辑副本溢出

    #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);
        }
    }

【讨论】:

  • 我不确定如何在 Node.js JavaScript 中使用它,但我会尝试 :)
  • 在 Windows 10 上,我只能看到它在任务栏中闪烁窗口图标,但没有弹出。
  • 我在 Windows 10 上做同样的事情。我在控制台中运行它,然后点击离开。它只会闪烁图标,但不会打开窗口。是的,它确实找到了窗口。
  • 使用最新的,只是一个闪烁的图标。
  • @vitaly-t ok 这一次它确实有效 - 破解了按键,更改了 repo
【解决方案2】:

我不确定这是否是您问题的答案,但看起来这可以解决您的问题:Setting focus to a Windows application from Node-JS

如果有错误请见谅。

【讨论】:

  • 不能用那个。这是基于现在废弃的ffi 模块。我能够在 Node.js v8 下专门安装它,仅此而已。甚至不安装在 v6、v10、v12、v13 下。总之,没用。
猜你喜欢
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-21
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多