Microsoft Net Explorer was fully scriptable using OLE Automation. This functionality is no longer available with the new Microsoft Edge browser. This tip presents a way to automate Edge and other Chrome based browsers using only VBA.
- Download 2021-xi.cipher
Introduction
Internet Explorer classic (IE in the post-obit) was based on ActiveX technology. It was very piece of cake to automate IE for tasks like Webscraping or testing from OLE-aware programming languages similar VBA. But Microsoft volition stop support for IE in the near futurity and wants users to move to newer browsers like Microsoft Border.
Microsoft Border is no longer based on ActiveX technology. Microsoft seems uninterested in creating a drib-in replacement for the IE OLE Object. In that location are libraries that endeavour to fill up this gap using Selenium, see Seleniumbasic as an example. But this requires the installation of a Webdriver, which might not be viable in some environments. The following solution needs no boosted software, autonomously from a Chrome-based browser.
Go on in listen, that all running Border procceses must be terminated before running the code. Otherwise the tabs are opened in the currently running procedure, not the 1 that has been started and subsequent communication between VBA and Edge fails.
CDP Protocol
The lawmaking uses the Chrome Devtools Protocol (CDP) to communicate with the browser. A total documentation of the protocol tin be found here. The lawmaking implements only a very narrow prepare of functions:
- Basic functions to set the communication channel
- Navigation to a url
- Evaluate arbitrary JavaScript expressions in the context of a page and return the issue
But these functions should suffice to do bones Webscraping. The primary code is as follows:
Sub runedge() Dim objBrowser Every bit clsEdge Set objBrowser = New clsEdge Call objBrowser.start Telephone call objBrowser.attach(" ") Call objBrowser.navigate(" https://google.de") Phone call objBrowser.waitCompletion Call objBrowser.jsEval(" alarm(""hi"")") Call objBrowser.jsEval(" certificate.getElementsByName(""q"")[0].value=""automate edge vba""") Telephone call objBrowser.jsEval(" document.getElementsByName(""q"")[0].form.submit()") Phone call objBrowser.waitCompletion Phone call objBrowser.jsEval(" certificate.evaluate("".//h3[text()='Automate Chrome / Edge using VBA - CodeProject']"", document).iterateNext().click()") Call objBrowser.waitCompletion Dim strVotes As String strVotes = objBrowser.jsEval(" ctl00_RateArticle_VountCountHist.innerText") MsgBox (" end! Vote count is " & strVotes) objBrowser.closeBrowser End Sub The class clsEdge implements the CDP protocol. The CDP protocol is a message-based protocol. Messages are encoded equally JSON. To generate and parse JSON, the code uses the VBA-JSON library from here.
Low-Level Communication with Pipes
The low-level access to the CDP protocol is avaible by ii means: Either Border starts a small-scale Webserver on a specific port or via pipes. The Webserver lacks whatever security features. Any user on the computer has access to the webserver. This may pose no risks on unmarried user computers or dedicated virtual containers. Merely if the process is run on a terminal server with more than than one user, this is non acceptable. That'due south why the lawmaking uses pipes to communicate with Edge.
Edge uses the 3rd file descriptor (fd) for reading messages and the fourth fd for writing messages. Passing fds from a parent process to child process is mutual under Unix, but not under Windows. The WinApi call to create a child procedure (CreateProcess) allows to setup pipes for the three common fds (stdin, stdout, stderr) using the STARTUPINFO structure, run across CreateProcessA function (processthreadsapi.h) and STARTUPINFOA structure (processthreadsapi.h). Other fds cannot be passed to the child process.
In order to set the fourth and fifth fds, one must use an undocumented characteristic of the Microsoft Visual C Runtime (MSVCRT): If an awarding is compiled with Microsoft C, than i tin can laissez passer the pipes using the lpReserved2 parameter of the STARTUPINFO structure. Run across "Undocumented CreateProcess" for more details (roll down the folio).
The structure that tin be passed in lpReserved2 is defined in the module modExec.
Public Blazon STDIO_BUFFER number_of_fds Every bit Long crt_flags(0 To 4) As Byte os_handle(0 To 4) As LongPtr End Type
The structure is defined to pass v fds in the os_handle array. The values for the crt_flags array can be obtained from https://github.com/libuv/libuv/hulk/v1.ten/src/win/process-stdio.c. The fields of the struct must lie contiguously in retentivity (packed). VBA aligns struct fields to 4 byte boundaries (on 32-bit systems). That's why a second struct with raw types is divers.
Public Blazon STDIO_BUFFER2 number_of_fds As Long raw_bytes(0 To 24) As Byte End Type
After populating the STDIO_BUFFER struct, the content is copied using MoveMemory to the STDIO_BUFFER2 struct. The size of 25 bytes is enought to hold crt_flags (v bytes) and the pointers (20 bytes).
History
- viiith July, 2021: Initial version
- 18thBaronial 2021, added support for 64bit Function
- 3rdNov 2021, some pocket-sized improvements
0 Response to "Upload File to Web Page Using Vba"
Post a Comment