2017-04-09 32 views
0

我试图检测用户何时解锁他们的工作站。以下代码尝试使用WTSRegisterSessionNotification()注册窗口以接收会话更改消息。据说在此之后,我可以监听WM_WTSSESSION_CHANGE,它可以包含WTS_SESSION_UNLOCK作为参数。当用户解锁工作站时检测

问题:目前WTSRegisterSessionNotification()总是返回false。

任何人都知道我可以做到这一点?我在Windows 10 btw。

var {remote} = require('electron'); 
var ffi = require('ffi'); 
var winctl = require('winctl'); 

var NOTIFY_FOR_ALL_SESSIONS = 1; 
var WM_WTSSESSION_CHANGE = parseInt('0x02B1', 16); 

var hwnd = remote.getCurrentWindow().getNativeWindowHandle(); 

var wtsapi32 = ffi.Library('wtsapi32', { 
    'WTSRegisterSessionNotification': [ 'bool', [ 'int', 'int' ] ] 
}); 

// Attempt to register 
var isregistered = wtsapi32.WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_ALL_SESSIONS); 

console.log(isregistered); // <----- RETURNS 0...? 

IInspectable recommended GetLastError()。 这不是node-ffi不支持的东西。 https://github.com/node-ffi/node-ffi/issues/261

+1

从[documentation](https://msdn.microsoft.com/en-us/library/aa383841.aspx):*“如果函数成功,则返回值为TRUE,否则为FALSE。* *要获得扩展错误信息,请调用[GetLastError](https://msdn.microsoft.com/en-us/library/ms679360.aspx)。**“* – IInspectable

+0

嗨,感谢您的评论。看起来这不幸的是,当使用node-ffi时,这不是一个选项。我修改了这个问题,只是为了确保。还发现这个:https://github.com/node-ffi/node-ffi/issues/261 –

+0

呵呵。有人甚至去解决问题的麻烦,而且修复程序从未融入到项目中。恐怕这意味着你失明了。也许你可以编写一个简单的C DLL来代表你调用WTSRegisterSessionNotification并返回错误代码? –

回答

0

最终放弃了这个。我证实HWND是正确的,但无论如何,它仍然无法工作。我最终在C#中编写了一个小函数,并使用节点边缘从节点/电子内部执行它。

0

您不应该使用winctl.GetActiveWindow来获取HWND,因为您实际上不知道哪个窗口处于活动状态。至于我可以告诉GetActiveWindow电话GetForegroundWindow内部,这是疯狂的,原因有二:

  1. GetForegroundWindow返回用户桌面上的前景窗口,并可以在其他应用程序的窗口。
  2. Windows有一个名为GetActiveWindow的实际函数,它与调用GetForegroundWindow不一样。

创建一个隐藏本机窗口以某种方式或使用电子提供一个窗口(GetTopLevelNativeWindow吧?)

GetLastError因为你来不及调用返回错误的值。在你和本地Windows功能之间有一层厚厚的东西,在你重新获得控制之前,有人呼吁SetLastError。 'ffi'库需要一种方法来指定您希望在调用请求的函数后立即以您的名义调用GetLastError。

最后,Windows BOOL是int大小,我猜node.js将它视为一个字节?

+0

嘿谢谢你的答案。我转而使用Electron提供的getNativeWindowHandle()函数。我也尝试设置返回类型为int而不是bool,但它没有区别。仍然没有运气。 –

+0

要尝试的操作:调用IsWindow Windows函数以验证句柄是否有效。调用GetWindowThreadProcessId来验证HWND与GetCurrentProcessId处于同一个进程中。在调试器中运行它,以便找出真正的错误代码。 – Anders

+0

谢谢。我证实句柄是有效的,但它仍然无法工作。最后写了一个我用节点边执行的C#方法。 –