Ruby:Watir は、「デフォルト」デスクトップの非管理者アカウントで実行されている IE に接続できません

StackOverflow https://stackoverflow.com/questions/1473900

  •  16-09-2019
  •  | 
  •  

質問

アプリのアーキテクチャに関するいくつかの背景が必要です。

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が埋め込まれており、スレッド内でRubyスクリプトを実行します。

IE でリンク/ボタンをクリックするために、Watir は同期 'click' メソッドと非同期 'click_no_wait' メソッドを提供します。「click_no_wait」は、リンク/ボタンをクリックするために IE7 ウィンドウに接続し直すためのまったく新しい Ruby プロセスを生成します。

これが私にとって失敗していることです。click_no_wait は新しいプロセスを生成しているため。IE7 ウィンドウに接続してリンク/ボタンをクリックすることができないようです。IEが特定のページにポップアップするダイアログボックスのため、別のRubyスレッドがそれを閉じることができるように、「click_no_wait」を使用する必要があります。

いくつかのことを試してみました。- click_no_wait の代わりに fire_event('OnClick') を使用すると、'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:in `method_missing':Windows(win32olerruntimeerror)oleエラーコード:80040154 in hresultエラーコード:0x80020009例外が発生しました。c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:246:in "each" から

を含む:

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

さらに詳しい情報や曖昧さの解消ができる場合はお知らせください。:)

ありがとう、シェーン。

役に立ちましたか?

解決

[OK]を、私は私自身の問題を解決しました。

これはワチールは、IEウィンドウを列挙するために使用する方法(すなわち、Shell.Application)は、ユーザ空間を横切って動作しないことがわかります。だから私は、IEのウィンドウのためのIWebBrowser2 COMポインタを取得するために、中間アプリケーションを作成し、「PC =ワチール:: IE.bind(iWebBrowserPtr)」のため、このハンドルを使用するには「eval_in_spawned_process」ワチール機能を変更する必要がありました。

これは、私がのIWebBrowser2オブジェクトを取得するために、外部のアプリを必要としなかったが、私はRubyでそれを行う方法を知らなかった、と私はすでに、私は目的のために活用することができIE BHOのアプリを持っていた可能性があります。

このは今正常に動作します。 :)

ワチール/ページ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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top