Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't MSHTML for .Net have querySelector and querySelectorAll, or where are they?

I want to use MSHTML [1] to access DOM in IE, but I have just found out that it lacks querySelector and querySelectorAll methods in HTML document classes, which will otherwise be very helpful to obtain elements within a document by CSS selectors.

The only workaround I can think of for now is to do everything by executing a script, but it is awful.

Is there any MSHTML version that has the two methods (querySelector and querySelectorAll)? Is there any other libraries (hopefully, official .Net libraries by Microsoft) where the two methods or their equivalents are available?

[1] %ProgramFiles(x86)%\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll

like image 370
Dante May Code Avatar asked Jan 11 '23 10:01

Dante May Code


2 Answers

The querySelector() method and friends are alive and well in MSHtml and the IE DOM, the problem is that the PIA that most programmers have on their machine is heavily outdated. The one registered in the GAC on my machine carries a 7.0.3300.0 version number, that dates back to 2002.

There is a workaround for that, you can generate your own interop library and avoid the one in the GAC. The trick is to intentionally generate a mismatch by creating an interop assembly without a strong name so it cannot match the one in the GAC. Be sure to do this only on VS2010 or later, you want to take advantage of the Embed Interop Types feature.

Start the Visual Studio Command Prompt and navigate to your project directory. And execute this command:

  Tlbimp c:\windows\system32\mshtml.tlb

It will trundle for a handful of minutes, the type library is very large, and spit out several icky looking warnings that you can ignore. Go back to VS, remove the existing MSHTML reference and use Add Reference, Browse tab. Pick the MSHTML.dll file that was generated by Tlbimp.

Do keep in mind that you now use an interop library that is compatible with the IE version that you have on your machine. Not necessarily the version your user has, so technically it is possible for your program to fail. You'd have to be very unlucky.

like image 117
Hans Passant Avatar answered Jan 30 '23 20:01

Hans Passant


Yesterday I notice the same problem, I found a solution.

The Next example code works for me:

Document.querySelectorAll("#navbar_search>a").item(0).click();

If i try to do "the same", but with this code, it fails:

HTMLDocument doc;
doc = ie.Document;
doc.querySelectorAll("#navbar_search>a").item(0).click();

I'm not a COM expert but I thing the first solution is a late binding (dependences are resolved at run-time), while the second solution is a compliler-time binding and it depends on a 'good' predefined libary and that's not the case with mshtml.

like image 40
ventolino Avatar answered Jan 30 '23 21:01

ventolino