2009-09-24 27 views
2

上的應用程序的體系結構的一些背景知識,需要對IE:紅寶石:的Watir不能連接到在非管理員帳戶下運行 '默認' 桌面

的Windows 2003/Apache的V2.2/IE7 /的Watir-V1。 6.2/Ruby-v1.8.5

  1. Apache在'localsystem'帳戶下運行。
  2. 請求運行Watir腳本。
  3. Apache CGI在特定用戶下啓動IE7,例如, 'tester',並將IE7窗口附加到「默認」桌面環境。這使我們可以將VNC放入機器,並查看所有運行帳戶的所有IE7窗口。
  4. IE7已通過插件嵌入到進程中,並在線程中執行ruby腳本。

爲了點擊IE中的鏈接/按鈕,Watir提供了一個同步'點擊'方法和異步'click_no_wait'方法。 'click_no_wait'產生了一個全新的ruby進程來連接回IE7窗口點擊鏈接/按鈕。

這是我失敗的原因。由於click_no_wait正在產生一個新的進程。它似乎無法看到IE7窗口連接到它並點擊鏈接/按鈕。 我必須使用'click_no_wait',因爲IE會在某個頁面上彈出一個對話框,以便另一個ruby線程可以關閉它。

我試過幾件事: - 使用fire_event('OnClick')而不是click_no_wait會掛起像'click'這樣的腳本。 - 通過註釋'@ container.wait'來修改'點擊',但'點擊!'本身就是掛起等待對話框關閉的API。 - 使'click_no_wait'產生一個新的線程而不是一個進程',但其他線程似乎被暫停,而'點擊!'調用在該線程中執行。這很奇怪。 - 使用與產生IE7進程的代碼完全相同的代碼執行'click_no_wait'進程,但仍無法找到任何IE7窗口。

通過「默認」桌面如上所述,該產卵IE基本上沒有一系列的C++調用到IE7窗口附加到「winsta0」桌面的代碼:

- LogonUser() // log in as tester account 
- OpenWindowStation("winsta0") // to get default desktop 
- SetProcessWindowStation() 
- // add the user to interactive window station using (GetUserObjectSecurity, GetSecurityDescriptorDacl, GetAclInformation, AddAce, SetSecurityDescriptorDacl, SetUserObjectSecurity) 
- // add user to "default" desktop using APIs listed above. 
- CreateEnvironmentBlock 
- ImpersonateLoggedOnUser 
- CreateProcessAsUser('iexplore.exe') 
- // cleanup 

運行下的下面的Watir腳本特定用戶IE7下產量運行:

$IE = Watir::IE.attach(:title, /Google/) 
$IE.button(:name, 'btnG').click! 

C:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:246:在`method_missing'中:Windows(WIN32OLERuntimeError) OLE錯誤代碼:80040154在 HRESULT錯誤代碼:0x80020009 發生異常。從C:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:246:在 「每個」

其中包含:

c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:246 
shell = WIN32OLE.new("Shell.Application") 
windows = shell.Windows ## Fails here 

讓我知道,如果我可以提供更多的細節或消除歧義! :)

謝謝, 謝恩。

+0

你也應該在這裏問:http://groups.google.com/group/watir-general/(1600+的Watir用戶那裏) 。 – 2009-09-25 08:02:56

+0

謝謝Željko,我會這麼做的。 – Shane 2009-09-25 16:40:16

+0

有可能我誤解你說的話。 但我告訴, 您使用click_no_wait治療對話框(IE對話框)? 是模態對話框嗎? 如果這是模態對話框,您應該關閉它,否則它不會繼續。我認爲。 – tknv 2009-09-28 06:26:59

回答

0

好吧,我已經解決了我自己的問題。

事實證明,Watir用來枚舉IE窗口(即Shell.Application)的方法不適用於所有用戶空間。所以我必須編寫一箇中間應用程序來檢索IE窗口的IWebBrowser2 COM指針,並修改'eval_in_spawned_process'Watir函數以使用'pc = Watir :: IE.bind(iWebBrowserPtr)'的句柄。

這可能是我不需要外部應用程序來檢索IWebBrowser2對象,但我不知道如何在Ruby中做到這一點,我已經有一個IE BHO應用程序,我可以用於此目的。

這現在工作正常。 :)

的Watir /頁container.rb:56

# This evaluates a cmd (e.g. "button(:id, 1).click!") in a new ruby process 
# This is to primarily avoid a script hanging while a modal dialog is displayed in IE. 
# It gets an IE handle from our IE BHO based off of window handle. It needs to do this 
# to get around the problem of finding the IE window itself using Shell.Application 
# which does not work across User-contexts. 
# Note: This change probably invalidates the Watir unit-test for this API. 
def eval_in_spawned_process(command) 
    command.strip! 
    load_path_code = _code_that_copies_readonly_array($LOAD_PATH, '$LOAD_PATH') 
    ruby_code = "require 'watir/ie'; " 
    ruby_code << 'controller = WIN32OLE.new("HttpPlugin.Controller"); ' 
    ruby_code << "window = controller.BrowserFromHWND(#{hwnd}); " 
    ruby_code << "pc = Watir::IE.bind(window); " 
    ruby_code << "pc.#{command}; " 
    exec_string = "start rubyw -e #{(load_path_code + '; ' + ruby_code).inspect}" 
    result = system(exec_string) 
end