2010-06-22 84 views
3

我需要以編程方式將RDP指向虛擬機(XP SP3/.NET3.5/VS 2008),(證書已保存在.rdp文件中)並進行UI自動化測試。由於我們的域安全性,我需要以編程方式回答交互式登錄的「確定」。我可以在登錄後訪問其他對話窗口和SendMessages按鈕等,但我無法讓我的SendMessage在此初始屏幕上工作。我用spy ++來捕獲當我按下Enter鍵時實際發送的內容,當我在運行我的程序時在間諜++日誌中查看響應時,似乎能夠複製這些消息,但無論我在消息中使用什麼變體,都不會發生任何事情。 我想知道是否甚至有可能以編程方式執行此操作,還是操作系統由於安全問題而阻止了這種自動化?編程RDP登錄和SendMessage

我在間諜++看到,當我按下回車鍵的消息(初始畫面上似乎任何鍵都可以)我看到:

WM_KEYDOWN nVirtKey:00FF cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 Up:0 
WM_KEYUP nVirtKey:00FF cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:1 Up:1 

當我練習下面的代碼,看發來的短信IHWindowClass(下面hwnd6)我看到我生成上述消息到該窗口。任何幫助,將不勝感激!

這裏是代碼的相關章節:

'UIntPtr ip = new UIntPtr(0x0D); //ENTER 
UIntPtr ip2 = new UIntPtr(0xFF); //00FF 
UIntPtr kyDwnlParam = new UIntPtr(0x001); 
UIntPtr kyUplParam = new UIntPtr(0xc0000001); 

// used UISpy to get these class names... 
string lpszParentClass = "TscShellContainerClass"; 
string lpszParentWindow = "test2 - test2 - Remote Desktop Connection"; 
string lpszClass2 = "TscShellAxHostClass"; 
string lpszClass3 = "ATL:2D33D580"; 
string lpszClass4 = "UIMainClass"; 
string lpszClass5 = "UIContainerClass"; 
string lpszClass6 = "IHWindowClass"; 


hWnd2 = FindWindowEx(ParenthWnd, IntPtr.Zero, lpszClass2, IntPtr.Zero); 
hWnd3 = FindWindowEx(hWnd2, IntPtr.Zero, lpszClass3, IntPtr.Zero); 
hWnd4 = FindWindowEx(hWnd3, IntPtr.Zero, lpszClass4, IntPtr.Zero); 
hWnd5 = FindWindowEx(hWnd4, IntPtr.Zero, lpszClass5, IntPtr.Zero); 
hWnd6 = FindWindowEx(hWnd5, IntPtr.Zero, lpszClass6, IntPtr.Zero); 

string hexValue = hWnd6.ToString("X"); //Convert to hex to use find in spy++ 

SetForegroundWindow(hWnd6); // for good measure.... 

// tried this.... 

SendMessage(hWnd6, (uint)WindowsUtilities.WindowsMessages.WM_KEYDOWN, ip2, kyDwnlParam); 
SendMessage(hWnd6, (uint)WindowsUtilities.WindowsMessages.WM_KEYUP, ip2, kyUplParam); 

// tried this.... 

SendMessage(hWnd6, (uint)WindowsUtilities.WindowsMessages.WM_KEYDOWN, ip, kyDwnlParam); 
SendMessage(hWnd6, (uint)WindowsUtilities.WindowsMessages.WM_KEYUP, ip, kyUplParam); 

// tried this... 
SendMessage(hWnd6, (uint)WindowsUtilities.WindowsMessages.WM_CHAR, ip, UIntPtr.Zero); 
SendMessage(hWnd6, (uint)WindowsUtilities.WindowsMessages.WM_CHAR, ip, UIntPtr.Zero);' 

回答

0

就快成功了,有一對夫婦,你需要發送到準備好接受鍵盤輸入RDP會話等消息。用Spy ++你應該看到更多的消息被髮送。

我能得到的字母「A」與下面的代碼輸入到記事本窗口(或理論上什麼都在RDP會話中的活動窗口):

SendMessage(cWind, (int)WM.IME_SETCONTEXT, new UIntPtr(0x00000001), new UIntPtr(0xC000000F)); 
SendMessage(cWind, (int)WM.IME_NOTIFY, new IntPtr(0x00000002), new IntPtr(0x00000000)); 
Thread.Sleep(1); 

SendMessage(cWind, (int)WM.SETFOCUS, new UIntPtr(0x00203794), new UIntPtr(0x00000000)); 
Thread.Sleep(1); 
//Random keypress 
SendMessage(cWind, (int)WM.KEYDOWN, new UIntPtr(0x000000FF), new UIntPtr(0x00000001)); 
SendMessage(cWind, (int)WM.KEYUP, new UIntPtr(0x00000041), new UIntPtr(0xC0000001)); 
Thread.Sleep(1); 
//A key presses 
SendMessage(cWind, (int)WM.KEYDOWN, new IntPtr(0x00000041), new IntPtr(0x001E0001)); 
SendMessage(cWind, (int)WM.KEYUP, new UIntPtr(0x00000041), new UIntPtr(0xC01E0001)); 

睡可能或可能並不是必需的,但Spy ++顯示這些呼叫正在返回,所以我在繼續之前等待一會兒。你應該也可以「撤消」setfocus/setcontext操作,但是爲了我的需要,這樣做的確很好。 (Spy ++會顯示細節)

0

正如@Spike所說,你需要發送IME_SETCONTEXT和IME_NOTIFY。 我測試了代碼,它抓取輸入,但是,它只發送字母'a',即使我發送VK_A - VK_Z。

   SendMessageKey.SimulateKey.SendMessage((IntPtr)hwnd, SendMessageKey.MessageCode.WM_IME_SETCONTEXT, 0x00000001, 0xc000000f); 
       SendMessageKey.SimulateKey.SendMessage((IntPtr)hwnd, SendMessageKey.MessageCode.WM_IME_NOTIFY, 0x00000002, 0x00000000); 
       SendMessageKey.SimulateKey.SendMessage((IntPtr)hwnd, SendMessageKey.MessageCode.WM_SETFOCUS, 0x00000000, 0x00000000); 

發送VK_A之前(例如),Winspector還檢測WM_KEYDOWN WM_KEYUP +與255的未知值/鍵碼我堅持在這裏,我很抱歉。 也許你會發現什麼是錯的。