2010-11-23 84 views
3

的Visual C++ 2008OpenInputDesktop(),以確定安全/登錄桌面

如何建立當前的交互式用戶是否是在任的鎖定桌面(windows鍵L)或關機屏幕(Vista或7)在退出時等待程序關閉。

HDESK hd = OpenInputDesktop(0,false,READ_CONTROL);

這適用於默認桌面上的用戶應用程序,但在鎖定或關閉桌面時出現錯誤代碼5,因爲我知道用戶無權打開安全桌面對象。

從在SYSTEM帳戶下運行的服務調用此函數會返回錯誤1(無效函數)。我相信服務在任何情況下都會出現錯誤的會話(會話0),並且無法確定任何其他會話的交互式桌面。

我有一個應用程序在當前交互式用戶下運行,而且系統服務正在運行,因此可以從兩者中執行代碼。

我是否應該嘗試枚舉所有會話,Window工作站和桌面?

即使那麼我如何確定當前的交互式桌面,如果我只能從會話0中的SYSTEM服務調用OpenInputDesktop?

+0

也許答案是以某種方式監視用戶切換桌面的時間?那可能嗎? – Peter350 2010-11-23 21:03:43

回答

3

我想你可以嘗試以下方法:

  • 從當前的交互式用戶運行的進程:
    使用WTSRegisterSessionNotification爲會話更改通知註冊。一旦註冊,交互式進程將獲得登錄/註銷通知。更多信息可以在這裏找到:
    http://msdn.microsoft.com/en-us/library/aa383841.aspx
    http://blogs.msdn.com/b/oldnewthing/archive/2006/01/ 04/509194.aspx

  • 從服務(會話0中運行):
    • 使用GetProcessWindowStation獲得服務的當前站手柄,並將其保存以備後用。
    • 使用WTSGetActiveConsoleSessionId獲取當前交互式會話的會話標識。
    • 使用WTSQuerySessionInformationWTSWinStationName信息類獲取與當前會話ID對應的電臺名稱。
    • 使用OpenWindowStation打開本站。使用SetProcessWindowStation將此工作站設置爲您的服務流程。
    • 現在,您可以使用OpenInputDesktop來檢查用戶是否已登錄。
    • 通過調用CloseWindowStation關閉打開的交互式窗口工作站。通過撥打電話號碼SetProcessWindowStation來重置原始的窗口服務站,並保存之前保存的電臺句柄。

PS:目前,"WinSta0"是在Windows中唯一的互動站。所以,您可以跳過WTSGetActiveConsoleSessionIdWTSQuerySessionInformation調用。

+0

我不認爲第二種方法正常運行。在會話0中運行的服務將失敗SetProcessWindowStation()將session1中的winsta0設置爲我自己。因爲SetProcessWindowStation()上的窗口工作站必須與當前會話關聯。 – sMiLo 2015-07-03 02:45:19

1

當心: MSDN約WTSQuerySessionInformationWTSWinStationName

注:儘管它的名字,指定此類型不返回窗口站名。而是返回遠程桌面服務會話的名稱。每個遠程桌面服務會話都與一個交互式窗口站相關聯。目前,由於交互式窗口站唯一支持的窗口站名是「WinSta0」,因此每個會話都與其自己的「WinSta0」窗口站相關聯。有關更多信息,請參閱窗口站。