jarmo / RAutomation

RAutomation
MIT License
100 stars 33 forks source link

Convert UiaDll to MC++ DLL #34

Closed leviwilson closed 11 years ago

leviwilson commented 11 years ago

Better ms_uia Support

Description

After poking around more with using COM and the UIA libraries, I noticed that it was flaky at best. I was unable to find items like UISpy said I should be able to with COM / C++. Using .NET yielded much better results, so I spiked out being able to invoke a MC++ DLL from Ruby using FFI to see if it would work. This is the result.

Changes / Features

jarmo commented 11 years ago

this will require .NET 4.0, but I plan on bumping this dependency down to .NET 3.0 later What happens if user does not have .NET installed or has older version than required?

Can you please add some specs too which fail without your changes and pass with them?

leviwilson commented 11 years ago

I certainly can add specs. I'll look again, but I thought if I added them they'd have to pass for all adapters.

I will investigate missing the .NET framework as well.

jarmo commented 11 years ago

You can add adapter specific specs too. There are some already under https://github.com/jarmo/RAutomation/tree/master/spec/adapter

leviwilson commented 11 years ago

Yep, just saw that...sorry about that, I will add them.

What were your thoughts around .NET? XP comes default with .NET 2.0. But with any service packs I imagine that 3.0 would be on there for sure.

jarmo commented 11 years ago

My question about .NET was if there will be any meaningful error message shown if for some reason .NET is missing or older or if it will just crash :)

leviwilson commented 11 years ago

Well, it should be meaningful....it will blow up saying it couldn't load the assembly I'm guessing, what more would a user want? :-P I'll try to get an instance up somewhere of an out-of-the-box XP machine and see what it informs me.

leviwilson commented 11 years ago

@jarmo have you gotten the tests to run on XP before? I have to go out of my way to not have the .NET 4 framework installed (i.e. I cannot install git for Windows). I get ruby going and the specs fail immediately in the win_32 specs when it loads the IAccessibleDLL.dll. I installed the MSVCRT from the redistributable package (as Dependency Walker indicated it was a problem) and it still fails to load.

Long story short, how would you like for me to proceed to test this? Installing git on Windows at all installes the .NET 4.0 framework.

leviwilson commented 11 years ago

What I've Found So Far

Running RAutomation Specs from master on XP and Vista

So, I've had limited success getting RAutomation to work on both Windows XP and Windows Vista. When I run

rake spec:ms_uia

I get the following error when it first loads the UiaDll.dll:

RAutomation::Buttons
UiaDll: CoCreateInstance failed. hr = 0x80040154  Window#buttons returns all buttons (FAILED - 1)
  Window#buttons with parameters returns all matching buttons (FAILED - 2)

And the following error on the individual specs (I'm sure related to the first):

  1) RAutomation::Buttons Window#buttons returns all buttons
     Failure/Error: SpecHelper::navigate_to_simple_elements
     LoadError:
       Could not open library 'C:/Users/Levi/git/RAutomation/lib/rautomation/adapter/ms_uia/../../../../ext/UiaDll/Release/UiaDll.dll': A dynamic link library (DLL) initialization routine failed.

I may be missing something, but I have not been able to get these to work.

update: KB971513 explains that you need the stand-alone installs to get this working on Windows XP as well as Windows Vista.

Using MC++ for ms_uia Adapter in RAutomation

One issue that I did not think about is when you build MC++ DLLs, the /MT and /clr switches are mutually exclusive, meaning that it doesn't seem that you can build a MC++ DLL and also statically link with the CRT. This makes sense, as I'm sure that .NET needs to do some fancy stuff when mixing both C++ and .NET code. That being said, the way to fix it would be to install the C-Runtime redistributable as well as .NET 4.0 in order for the changes I made to work.

Where to Go?

I'm not sure how I should proceed from here. Would it be fine to make this requirement clear (that you need the CRT installed and .NET) or should there be another adapter added to RAutomation. Please let me know your thoughts.

jarmo commented 11 years ago

You could not install git, by just downloading zip file from GitHub for example or just copying project from one pc to other and then just running rspec spec command instead of rake spec.

I remember that there was some update you needed to do to use on XP prior SP2 or something. Maybe that's the one found by you. That's one of the reasons why MsUia adapter is not default one for RAutomation. There's just too many XP users around to make installation of RAutomation harder :(

I'm thinking that we could make the requirements clear, but not make that adapter as default as stated above - i'd like to keep the first installation experience as smooth as possible. Thoughts?

leviwilson commented 11 years ago

I agree. I think having adapter specific installation instructions in the README would help out a lot. autoit already requires a separate install, and this would only require the additional C-runtime redistributable and the .NET framework.

Also, I did get it to fail in the manner you were looking for. When you don't have .NET 4 it fails to load UiaDll.dll and says that there was a bad image format. In my opinion, just making the instructions clearer for what the adapter requires would be enough.

jarmo commented 11 years ago

By the way - AutoIt does not require any separate intalls. It will do regsvr32 when loading autoit fails for the first time and install everything behind user's back.

On Tue, Nov 6, 2012 at 3:58 PM, Levi Wilson notifications@github.comwrote:

I agree. I think having adapter specific installation instructions in the README would help out a lot. autoit already requires a separate install, and this would only require the additional C-runtime redistributable and the .NET framework.

Also, I did get it to fail in the manner you were looking for. When you don't have .NET 4 it fails to load UiaDll.dll and says that there was a bad image format. In my opinion, just making the instructions clearer for what the adapter requires would be enough.

— Reply to this email directly or view it on GitHubhttps://github.com/jarmo/RAutomation/pull/34#issuecomment-10111286.

leviwilson commented 11 years ago

Odd. When I first ran the specs on Windows 7, the AutoIt specs failed until I installed it.

jarmo commented 11 years ago

Didn't you see error message outputted from this method? https://github.com/jarmo/RAutomation/blob/master/lib/rautomation/adapter/autoit/window.rb#L15-23

J.

On Tue, Nov 6, 2012 at 4:05 PM, Levi Wilson notifications@github.comwrote:

Odd. When I first ran the specs on Windows 7, the AutoIt specs failed until I installed it.

— Reply to this email directly or view it on GitHubhttps://github.com/jarmo/RAutomation/pull/34#issuecomment-10111482.

leviwilson commented 11 years ago

I didn't on my Windows 7 install. I'll check on my other VMs to see if I can see that.

leviwilson commented 11 years ago

Yep, I saw that message. Must not have noticed before on Windows 7.

leviwilson commented 11 years ago

Anything else you need me to look into before getting this pull request into master?

jarmo commented 11 years ago

Sorry, i didn't notice you have added specs too. Added one little comment there and after that i'll try to run specs on my machine and if everything passes i'll merge it in :)

leviwilson commented 11 years ago

I'm sure you've seen this, but there is an oddity with the table_spec.rb that runs after the select_list_spec.rb when you run the spec:ms_uia. I'm trying to track it down, but the table specs fail if they run after the select list specs. If I flop the order, they are both fine. Did you see this behavior?

leviwilson commented 11 years ago

I'm not sure why this is happening, but with the newly built MC++ UiaDll.dll, when the Table class calls get_current_control_type, it is returning UIA_DataGridControlTypeId (50028) vs. the expected UIA_ListControlTypeId (50008). I noticed that the UIA_DataGridControlTypeId (500028) is not defined in ms_uia\constants.rb. I'm not sure why this would be happening or if these control types are interchangable. When I lookup the control in UISpy, it shows ControlType.DataGrid.

I'm thinking that line 72 of table.rb should read:

def exist?
  super && considered_a_table?
end

def considered_a_table?
  matches_type?(Constants::UIA_LIST_CONTROL_TYPE) || matches_type?(Constants::UIA_DATA_GRID_CONTROL_TYPE)
end

Thoughts?

jarmo commented 11 years ago

To be honest, i don't have any ideas. Maybe @enkessler has some, since he has also done changes in MsUia adapter. I've been only on Win32 and AutoIt adapters from the start.

jarmo commented 11 years ago

Thank you for your hard work :) Does that mean we can close #15 now?

leviwilson commented 11 years ago

Yep, as long as they use the ms_uia adapter. win32 is definitely broken, and not sure about autoit.