这个问题有点像之前谈话的“附带”: 如何在 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 代码来执行此操作。
这是新的,尝试重写未成功
我无法给您一个完全涵盖您提出的两点的答案……但希望这能让您朝着正确的方向前进。顺便说一句,我假设您使用的是 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 类型库文件相同的文件夹中。
由于有些人不知道需要安装主插件,因此还添加了插件安装过程。 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