2017-04-09 60 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#方法。 –