如何關閉遠程桌面后仍處於可交互狀態


如何關閉遠程桌面后仍處於可交互狀態

標簽(空格分隔): windows 服務器 遠程桌面 模擬鼠標
[轉載自]

  1. http://blog.chenxu.me/post/detail?id=68b1ced9-65b4-4f71-8325-582c70cd996b
  2. http://blog.csdn.net/sogouauto/article/details/43269045
  3. http://ju.outofmemory.cn/entry/181730

  默認情況下,當用戶沒有在 Windows 上執行任何輸入(沒有鼠標鍵盤等的輸入)並保持一定時間后,Windows 會自動切換到鎖屏模式(或屏保模式),甚至待機。
  一般情況下,這樣不會有任何問題,而且也是推薦的設置(出於安全和節能的角度)。但是,如果這台電腦被用於進行一些自動化的測試,尤其是涉及到 UI 的交互操作時(比如,測試過程中用腳本操控鼠標來模擬點擊一個按鈕),這將會是個很大的問題:鼠標鍵盤失效了!UI 自動化做不下去了!
  解決這個辦法的方案很簡單:設置 Windows 的電源模式,讓 Windows 不要自動鎖屏和待機,同時去掉屏保。

問題進階

  UI 自動化測試期間,執行測試的電腦幾乎不能繼續被他人使用(因為鼠標、鍵盤等輸入設備此時需要響應自動化測試腳本)。為了不影響電腦使用,一般會搭一個虛擬機,然后遠程連接到虛擬機里,在虛擬機里執行 UI 自動化測試。
  但是,萬一你不小心把某個遠程桌面“最小化”了...Oops,你的自動化測試就掛了。既然連最小化都會失敗,相信你已經猜到直接關閉遠程桌面的后果了。
  為什么最小化或關閉遠程連接的桌面會導致自動化測試失敗呢?

概念介紹

  要解釋清楚這個原因,首先必須要了解3個在Windows 操作系統中的經常用到,卻很陌生的對象:Session、Windows Station 和 Desktop。

Session

  用戶會話,每個登錄操作系統的用戶都會分配一個唯一的登錄會話,用於標識該用戶。操作系統(Vista 及以上)保留0號會話給一些系統服務及用戶態的驅動使用,第1個登錄系統的用戶使用的 Session ID 為1,該用戶執行的所有應用程序都在 Session 1 下執行。
  我們可以打開任務管理器,切換到進程列表,然后在菜單->視圖->選擇列中,勾選 Session ID 列。

此處輸入圖片的描述

  如果有其它的用戶登錄到系統,就會看到 Session ID 大於1的情況,比如遠程桌面。

Windows Station

  Station 可以理解為工作站,它被認為是桌面和進程的安全邊界。因此,每一個 session 都會包含多個 station,而每一個 Station 又包含1個或多個 Desktop。
  但是,多個 Station 中,只有名字叫 Winsta0 的 Station 才是交互式的 station,也就是說只有它才能有 UI 並接受用戶輸入。所以每個 Session 都有一個叫 Winsta0 的用戶進行交互。

Desktop

  這里的 Desktop 並不是我們進入系統后所看到的那個藍底的桌面(,我們看到的這個桌面,實際上只是一個窗口)。而是邏輯上的一個顯示對象,它包含可顯示的 GUI 對象(比如窗口、菜單、鈎子等)。一般情況下,WinSta0 包含至少三個Desktop:登錄(WinLogon)、屏保(ScreenSaver)和默認(Default,能看到所有應用程序的地方)。
  同一時刻只能有一個Desktop處於激活狀態(而能激活的 Desktop 只能屬於 Winsta0)。用戶還沒登錄的時候,登錄桌面處於激活狀態。登錄之后,默認的Desktop處於激活狀態。當達到系統電源設置的某個點的時候,系統切換到屏保,此時屏保Desktop處於激活狀態。當用戶按下 Ctrl + Alt + Delete 時,切換到登錄Desktop,此時登錄Desktop處於激活狀態。
  激活狀態的Desktop才能接收用戶輸入,鈎子才能獲取其中的某個窗口消息。
  如果你已經體驗過 Win10,那應該就會知道 Win10 提供了很方便的創建多個Desktop的方式。
此處輸入圖片的描述

關於上述三個對象更多的解釋,請大家查看下面的參考鏈接。

Desktop
Window Stations
Why do UI macros fail when I disconnect or minimize the Remote Desktop/Terminal Services session?
Running Tests via Remote Desktop - Overview
Keep an Active Session Running on the Execution Server

原 因

  了解了上述三個對象后,就可以比較容易的解釋出現問題的原因了。

最小化
  最小化會讓遠程桌面的會話切換到無圖形界面的模式,這自然就無法繼續接收鼠標、鍵盤的指令了。

關閉遠程桌面
  關閉遠程桌面會讓系統切換到登錄Desktop的界面,而在該Desktop上並沒有我們打開的其它窗口,因此會導致 UI 自動化測試失敗。

解決辦法

最小化 (注意,正在測試...並未成功,有另一篇文章提到修改方法應為 從機器A通過遠程桌面連接機器B,則需要在機器A上修改注冊表)

通過設置注冊表的值可以阻止切換到無圖形界面。

32位系統
  找到 HKEY_LOCAL_MACHINE\Software\Microsoft\Terminal Server Client,創建一個 DWORD 類型的值,名字叫做 RemoteDesktop_SuppressWhenMinimized,然后設置值為 2。

64位系統
  找到 HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Terminal Server Client,然后和 32 位一樣創建一個DWORD 類型的值,名字叫做 RemoteDesktop_SuppressWhenMinimized,並設置值為 2。

  上面的改動會應用於整個機器,如果只想應用於當前的用戶,把 LOCAL 替換成 USER。

關閉遠程桌面

方案一:
  在遠程桌面(被連接到的電腦)中先執行 query session 來查看當前登錄到的 session,(遠程桌面的 sessionName 都以 rdp-tcp 開頭)。

此處輸入圖片的描述

  然后用管理員用戶打開命令行工具,並執行 "tscon rdp-tcp#0 /dest:console",其中 rdp-tcp#0 為該該命令會關閉遠程桌面的連接,然后把連接返回給遠程的那台電腦(繞開登錄過程)。這里的 console 只是一個 session 的名字,而這個名字的意思並非是 C# 中 “控制台” 的意思,而是指帶有輸入輸出設備的機器,一般直接登錄電腦的會話就是 console。
  假設電腦A執行 mstsc 連接到電腦B(,連接成功后,電腦B黑屏),此時在電腦B上執行上述命令后(替換對應的session名字),電腦A中的遠程連接窗口會被關閉,並提示遠程連接會話已經終止。電腦B(假設運行在另一台物理機上)會恢復到已經登錄的狀態,如果需要重新讓電腦B恢復鎖屏狀態,可以在電腦B上執行如下命令:

rundll32.exe user32.dll,LockWorkStation

方案二:
  假設用於跑 UI 自動化的機器是虛擬機A,現在再使用另一台虛擬機B作為中轉。本機先連接到虛擬機B,然后再從虛擬機B連接到虛擬機A,最后斷開虛擬機B。
此處輸入圖片的描述

方案三:(引自 UI自動化中關閉遠程桌面連接,鼠標鍵盤失效的解決方案)

  遠程桌面mstsc遠程登錄虛擬機時,在虛擬機中新建文本文檔,寫入內容

@%windir%\System32\tscon.exe 0 /dest:console
@%windir%\System32\tscon.exe 1 /dest:console
@%windir%\System32\tscon.exe 2 /dest:console

將文本文檔重新命名為‘Close_RDP’,並將后綴名改為‘.bat’,雙擊文件‘Close_RDP.bat’關閉遠程鏈接。

方案四:(引自 [UI測試]遠程桌面連接的困擾)

  並沒有找到例子,有時間我會寫上例子。
  使用C#開源遠程桌面連接軟件Multi RDP Client .NET,當遠程連接上后,最小化的情況下,鼠標鍵盤模擬仍然是生效的。另外由於是開源軟件,所以我們可以在源碼基礎上,擴展自己的功能,比如說在自動化測試過程中,接收請求,自動遠程連接相應機器,來滿足自動化測試的需求。另外,使用第三方遠程連接軟件,我們可以將軟件的數據保存到遠程的數據庫中,這樣,我們只需要有軟件,不需要知道機器密碼就可以使用執行機器了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM