使用 VBA 下载 Chrome / ChromeDriver 版本 115

问题描述 投票:0回答:2

这个问题有点像之前谈话的“附带”: 如何在 VBA 中自动更新 ChromeDriver 或 EdgeDriver?

从 Chrome 版本 115 开始......它们有一个新的目录结构。 https://googlechromelabs.github.io/chrome-for-testing/

Chrome:https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/115.0.5790.110/win64/chrome-win64.zip

ChromeDriver:https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/115.0.5790.110/win64/chromedriver-win64.zip

像往常一样,他们没有 VBA 代码。 JSON: https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json

好消息是 Chrome 和 ChromeDriver 现在保证匹配,因为它们都是同时更新的。

坏消息是您仍然需要下载并安装 ChromeDriver 作为单独的任务。

Google 更新由我们的 IT 部门处理,因此我无法将其编码为: A) 检查 Chrome 的当前版本。 (可以使用现有的方法从Windows注册表中获取它吗?) b) 下载并安装匹配的 ChromeDriver。

我需要比我更聪明的人来创建正确的 VBA 代码来执行此操作。

这是新的,尝试重写未成功

vba ms-access installation selenium-chromedriver driver
2个回答
0
投票

我无法给您一个完全涵盖您提出的两点的答案……但希望这能让您朝着正确的方向前进。顺便说一句,我假设您使用的是 Windows 设备。

对于A点“当前版本的Chrome”:

您可以通过此功能访问版本(实际上是“文件版本”或“产品版本”)

' ---------------------------------------------------------------------------------------------------------------------
' Purpose: Try to get a property of a file
' Parameter sFilePath (String): The full path to the file
' Parameter sPropertyName (String): The file property to get details for eg "Size", "Date accessed", "Product version"
'     ... which properties are available depends on the file, the parent folder and the OS
' Parameter outsPropertyValue (String): If the file has such a property, will be updated to hold the property value
' Returns (Boolean): True if the property exists, False otherwise
' ---------------------------------------------------------------------------------------------------------------------
Private Function TryGetFileProperty(sFilePath As String, sPropertyName As String, ByRef outsPropertyValue As String) _
        As Boolean
    ' for early binding, add a reference to 'Microsoft Shell Controls and Automation' and use the commented-out types
    Dim oShellApp As Object ' Shell32.Shell
    Dim oShellFolder As Object ' Shell32.Folder
    Dim oShellFolderItem As Object ' Shell32.FolderItem
    
    Dim lFileNameStart As Long
    lFileNameStart = InStrRev(sFilePath, "\")
    
    Set oShellApp = CreateObject("Shell.Application")
    Set oShellFolder = oShellApp.Namespace(Left$(sFilePath, lFileNameStart))
    Set oShellFolderItem = oShellFolder.Items.Item(Mid$(sFilePath, lFileNameStart + 1))
    
    ' file properties can only be accessed by index number, however, the index number (and therefore the maximum index
    ' number - here 350) can vary (by file / folder / Windows version?) so we iterate over all properties to find the
    ' one with a name that matches the supplied property name ... if we find the property with the supplied name, then
    ' return its value
    Dim i As Long
    For i = -1 To 350
        If StrComp(oShellFolder.GetDetailsOf(oShellFolder.Items, i), sPropertyName, vbTextCompare) = 0 Then
            outsPropertyValue = oShellFolder.GetDetailsOf(oShellFolderItem, i)
            TryGetFileProperty = True
            Exit Function
        End If
    Next i
End Function

...该函数被记录下来以解释它的作用以及它是如何做到的,所以除了提供这个用法示例之外,我不会进一步深入它:

Sub ExampleUsage()
    Const sFILE_PATH As String = "C:\Program Files\Google\Chrome\Application\chrome.exe"
    Const sPROPERTY_NAME As String = "Product version"
    Dim sPropertyValue As String
    If TryGetFileProperty(sFILE_PATH, sPROPERTY_NAME, sPropertyValue) Then
        Debug.Print sPROPERTY_NAME & " is " & sPropertyValue
    Else
        Debug.Print "Could not get the " & sPROPERTY_NAME
    End If
End Sub

...在我的设备上,这会在立即窗口中打印“产品版本为 115.0.5790.110”。

顺便说一句,如果您想查看特定文件的所有可用属性,请使用以下命令:

Sub LogAllFileProperties(sFilePath As String, Optional bOnlyWithValidValue As Boolean = True)
    ' for early binding, add a reference to 'Microsoft Shell Controls and Automation' and use the commented-out types
    Dim oShellApp As Object ' Shell32.Shell
    Dim oShellFolder As Object ' Shell32.Folder
    Dim oShellFolderItem As Object ' Shell32.FolderItem
    
    Dim lFileNameStart As Long
    lFileNameStart = InStrRev(sFilePath, "\")
    
    Set oShellApp = CreateObject("Shell.Application")
    Set oShellFolder = oShellApp.Namespace(Left$(sFilePath, lFileNameStart))
    Set oShellFolderItem = oShellFolder.Items.Item(Mid$(sFilePath, lFileNameStart + 1))

    Dim i As Long, sDetailName As String, sDetailValue As String
    For i = -1 To 350
        sDetailName = oShellFolderItem.Parent.GetDetailsOf(oShellFolder.Items, i)
        sDetailValue = oShellFolderItem.Parent.GetDetailsOf(oShellFolderItem, i)
        If Len(sDetailValue) > 0 Or (Not bOnlyWithValidValue And Len(sDetailName) > 0) Then
            Debug.Print Format(i, "000") & ": '" & sDetailName & "' = '" & sDetailValue & "'"
        End If
    Next i
End Sub

...只需将文件的完整路径传递给它即可。

对于B点“下载并安装ChromeDriver”:

我只能向您指出其他答案的方向,例如这个供下载。

假设您这样做是为了使用 SeleniumBasic,我相信(很高兴得到纠正!)ChromeDriver 实际上不需要“安装”,只需要解压下载的文件(同样有一个解压缩时的 SO 答案数,例如 this ),然后复制到与 SeleniumBasic 类型库文件相同的文件夹中。


0
投票

由于有些人不知道需要安装主插件,因此还添加了插件安装过程。 https://github.com/florentbr/SeleniumBasic/releases SeleniumBasic v2.0.9.0.exe 第一次安装完成后,必须转到“开始”>“运行 Selenium”的“启动 chrome”。 等待错误弹出并确认。这将自动安装 .net Framework。安装完成后,重新启动系统。 重启后运行此程序即可更新版本。

Sub updateSelenium()
' Since selenium might be installed in one of two folders under Windows, we need to find the correct folder first (Mac is not considered currently)
path1 = "C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\Chromedriver.exe"
path2 = "C:\Program Files\SeleniumBasic\chromedriver.exe"
If Dir(path1) <> "" Then TempDrvFile = path1
If Dir(path2) <> "" Then TempDrvFile = path2
foler = Left(TempDrvFile, InStrRev(TempDrvFile, "\")) 'Get the folder path and the path to chromedriver.exe
' If Selenium 2.0.9.0 is not installed, the user will be directed to the GitHub site to download and install it manually
If foler = "" Then
    msg = "(Please screenshot or capture this screen)" & vbCrLf
    msg = msg & "Cannot find the Selenium plugin folder. Please visit the website: " & vbCrLf & "https://github.com/florentbr/SeleniumBasic/releases"
    msg = msg & vbCrLf & "Download and install SeleniumBasic v2.0.9.0.exe" & vbCrLf & vbCrLf & "Would you like to visit now?"
    msg = msg & vbCrLf & vbCrLf & "Please note the following steps:" & vbCrLf & "After the first installation, go to Start > Run Selenium's 'start chrome'" & vbCrLf
    msg = msg & "Wait for the error message and confirm. It will auto-install .net framework. Restart your computer after installation." & vbCrLf & "Run this program again to update the version."
    x = MsgBox(msg, vbYesNo, "Plugin not installed")
    If x = 6 Then
    edgePath1 = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
    edgePath2 = "C:\Program Files\Microsoft\Edge\Application\msedge.exe"
    If Dir(edgePath1) <> "" Then edgePath = edgePath1
    If Dir(edgePath2) <> "" Then edgePath = edgePath2
    edgePath = """" & edgePath & """" & " https://github.com/florentbr/SeleniumBasic/releases"
    Call Shell(edgePath, vbNormalFocus)
    End If
Exit Sub
End If

' Get the current chromedriver version's first two digits, e.g., 117.0
Set oShell = CreateObject("wscript.shell")
errcode = oShell.Exec(TempDrvFile & " --version").StdOut.ReadAll
verarr = Split(errcode, " ")
chrdrv = verarr(1)
dotsarr2 = Split(chrdrv, ".")

' Obtain the current version of the Chrome browser, e.g., 117.0
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
chrversion = CreateObject("WScript.Shell").RegRead("HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon\version")
dotsarr = Split(chrversion, ".")
leftchrver = dotsarr(0) & dotsarr(1)

' Compare chromedriver and Chrome browser version numbers. If they are the same, exit (no update); otherwise, visit the official site to check the latest browser version and continue to download and replace
leftchrdrv = dotsarr2(0) & dotsarr2(1)
If leftchrver = leftchrdrv Then Exit Sub

' Access the official API to obtain version info and extract it. This info is in JSON format. The available chromedriver version for the current browser is also extracted
' This method of extracting from JSON is custom-made. It does not conform to standard JSON. We are unsure if the format will change in the future, and we don't want to include additional objects
Url = "https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json"
Call objHTTP.Open("GET", Url, False)
Call objHTTP.Send("")
version_number = objHTTP.responseText
' [The following logic is a specific way to parse the given JSON data.]
' ... [JSON parsing logic]

' Generate the download link (Note: we also need to consider the OS bit version, which might change the cmd part below). It is uncertain if the download URL will change in the future
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/linux64/chromedriver-linux64.zip"
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/mac-x64/chromedriver-mac-x64.zip"
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win32/chromedriver-win32.zip"
download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win64/chromedriver-win64.zip"
    Call objHTTP.Open("GET", download_url, False)
    Call objHTTP.Send("")

' Use ADODB.Stream to receive the file
Set fileStream = CreateObject("ADODB.Stream")
With fileStream
    .Open
    .Type = 1 ' Binary type
    .Write objHTTP.responseBody
    .Position = 0
    .SaveToFile foler & "chromedriver.zip", 2 ' Download the file to the Selenium folder. '2 means overwrite
    .Close
End With

' Use shell+cmd to delete old files. The kill method is blocked by Microsoft
Set oApp = CreateObject("Shell.Application")
 cmdCommand = "cmd /c del " & foler & "chromedriver.exe"    
        Call Shell(cmdCommand, vbHide)                         
        cmdCommand = "cmd /c del " & foler & "LICENSE.chromedriver"
        Call Shell(cmdCommand, vbHide)                            
            If Dir(foler & "chromedriver.exe") <> "" Then
            cmdCommand = "cmd /c taskkill /F /IM chromedriver.exe && cmd /c del " & foler & "chromedriver.exe"  
            Call Shell(cmdCommand, vbHide)
            End If
            If Dir(foler & "LICENSE.chromedriver") <> "" Then
            cmdCommand = "cmd /c taskkill /F /IM LICENSE.chromedriver && cmd /c del " & foler & "LICENSE.chromedriver"  
            Call Shell(cmdCommand, vbHide)
            End If

' Unzip the new chromedriver.exe to the directory. 16 is the force- replace option. Note that the file name inside the zip might vary depending on the system bit version
oApp.Namespace(foler).CopyHere oApp.Namespace(foler & "chromedriver.zip\chromedriver-win64").items, 16

End Sub
© www.soinside.com 2019 - 2024. All rights reserved.