Some Background on architecture of the app is needed:
Windows 2003/Apache-v2.2/IE7/Watir-v1.6.2/Ruby-v1.8.5
- Apache running under 'localsystem' account.
- Request to run a Watir script comes in.
- Apache CGI kicks off IE7 under a particular user, e.g. 'tester', and attaches the IE7 window to the "default" desktop environment. This allows us to VNC into the machine and see all IE7 windows from all the accounts running.
- IE7 has ruby embedded into the process through plugin and executes the ruby script in a thread.
For clicking on links/buttons in IE, Watir supplies a synchronous 'click' method and async 'click_no_wait' method. 'click_no_wait' spawns a completely new ruby process to connect back to the IE7 window to click the link/button.
This is what is failing for me. Since click_no_wait is spawning a new process. It cannot seem to see the IE7 window to connect to it and click on the link/button. I have to use 'click_no_wait' due to a dialog box that IE pops up on a certain page, so that another ruby thread can close it.
I've tried a few things: - using fire_event('OnClick') instead of click_no_wait hangs script like 'click' would. - Modifying 'click' by commenting out '@container.wait', but the 'click!' itself is the API that hangs waiting for the dialog box to close. - Make 'click_no_wait' spawn a new thread instead of a process', but other threads appear to be suspended while the 'click!' call executes in that thread. Which is strange. - Executing the 'click_no_wait' process using the exact same code that is used to spawn the IE7 process, but it still can't find any IE7 windows.
By 'default' desktop described above, the code that spawns IE basically does a series of C++ calls to attach the IE7 window to the 'winsta0' desktop:
- 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
Running the following Watir script under the particular user IE7 is running under yields:
$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 (WIN32OLERuntimeError) OLE error code:80040154 in HRESULT error code:0x80020009 Exception occurred. from c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:246:in "each"
Which contains:
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
Let me know if I can supply more details or disambiguation! :)
Thanks, Shane.