You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio构建Access可引用DLL时遇「无法添加指定文件引用」错误

解决VB Selenium DLL无法被Microsoft Access引用的问题

问题描述

我用Visual Basic结合NuGet的Selenium包开发了一个产权费用报价工具,代码在VS控制台项目中运行完全正常,但生成DLL后尝试作为Microsoft Access的引用时,弹出错误:「Can't add a reference to the specified file」。已经尝试过以下操作但无效:

  • 将所有依赖项复制到DLL所在目录(与Access数据库同目录)
  • 更换不同的.NET版本
  • 勾选项目属性中的COM兼容性选项
  • 以管理员身份打开VS构建
  • 构建前删除bin文件夹

工具核心代码如下:

Imports OpenQA.Selenium
Imports OpenQA.Selenium.Edge
Namespace TitleFeeCalculatorNamespace
    Public Class TitleFeeCalculator
        Public Function returnTitleFee(curCostofProperty As String, curMortgageAmount As String) As String
            ' Set up the Edge WebDriver
            Dim options As New EdgeOptions()
            options.AddArgument("headless") 'so opens in the background
            Dim driver As IWebDriver = New EdgeDriver(options)

            Try
                ' Navigate to the Title Fees Calculator form
                driver.Navigate().GoToUrl("https://www.anytitleco.com/Title.Site/Frontend/Calculators/TitleCalculator.aspx?state=NJ")

                ' Wait for the page to load (adjust delay as needed)
                Threading.Thread.Sleep(500)

                ' Select "Residential" from the Property Type dropdown
                Dim propertyTypeDropdown As IWebElement = driver.FindElement(By.Id("ddlPropertyType"))
                Dim propertyTypeOption As IWebElement = propertyTypeDropdown.FindElement(By.XPath("//option[text()='Residential']"))
                propertyTypeOption.Click()

                ' Select "Basic" from the Transaction Type dropdown
                Dim transactionTypeDropdown As IWebElement = driver.FindElement(By.Id("ddlTransactionType"))
                Dim transactionTypeOption As IWebElement = transactionTypeDropdown.FindElement(By.XPath("//option[text()='Purchase']"))
                transactionTypeOption.Click()

                ' Enter the Purchase Amount
                Dim purchaseAmountField As IWebElement = driver.FindElement(By.Id("txtPurchaseAmt"))
                purchaseAmountField.Clear()
                purchaseAmountField.SendKeys(curCostofProperty)

                ' Enter the Mortgage Amount
                Dim mortgageAmountField As IWebElement = driver.FindElement(By.Id("txtMortgageAmt"))
                mortgageAmountField.Clear()
                mortgageAmountField.SendKeys(curMortgageAmount)

                ' Click the "MTA as closing agent" checkbox
                Dim mtaCheckbox As IWebElement = driver.FindElement(By.Id("chkMTAAgent"))
                If Not mtaCheckbox.Selected Then
                    mtaCheckbox.Click()
                End If

                ' Submit the form
                Dim submitButton As IWebElement = driver.FindElement(By.Id("btnSubmit"))
                submitButton.Click()

                ' Wait to observe the result (adjust delay as needed)
                Threading.Thread.Sleep(500)

                ' Extract the Total Fees from the result table
                Dim totalFeesElement As IWebElement = driver.FindElement(By.XPath("//tr[contains(., 'TOTAL FEES')]/td[2]"))
                Dim totalFees As String = totalFeesElement.Text
                Return totalFees

            Catch ex As Exception
                ' Handle any exceptions
                Console.WriteLine("An error occurred: " & ex.Message)
                Return "0"

            Finally
                ' Close the browser
                driver.Quit()
            End Try
        End Function
    End Class
End Namespace

可能的解决方向

1. 匹配Access与DLL的平台和.NET版本

Access对目标平台和.NET版本兼容性要求严格:

  • 若使用32位Access,必须将VB项目的平台目标设置为x86(项目属性→生成→平台目标)
  • 优先选择.NET Framework 4.7.2或更低版本,Access对.NET Core/.NET 5+的原生支持有限

2. 完整配置COM可见性

仅勾选COM兼容性选项不够,需要确保:

  • 在项目属性→应用程序→程序集信息中,勾选「使程序集COM可见」
  • 为类和公开方法添加ComVisible特性,修改代码如下:
Imports System.Runtime.InteropServices
Imports OpenQA.Selenium
Imports OpenQA.Selenium.Edge

<ComVisible(True)>
Namespace TitleFeeCalculatorNamespace
    <ComVisible(True)>
    Public Class TitleFeeCalculator
        <ComVisible(True)>
        Public Function returnTitleFee(curCostofProperty As String, curMortgageAmount As String) As String
            ' 原有代码...
        End Function
    End Class
End Namespace
  • 构建后,用管理员身份运行命令提示符,通过regasm注册DLL:
    ' 32位系统/32位Access使用此路径
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe /codebase YourDllName.dll
    ' 64位系统/64位Access使用此路径
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /codebase YourDllName.dll
    

3. 处理Selenium原生依赖

Selenium的WebDriver(如msedgedriver.exe)是原生可执行文件,需手动配置:

  • 确保msedgedriver.exe与DLL、Access数据库在同一目录,且版本与本地Edge浏览器完全匹配
  • 在代码中显式指定WebDriver路径,避免自动查找失败:
    Dim driverService As EdgeDriverService = EdgeDriverService.CreateDefaultService("Access数据库所在目录的绝对路径")
    Dim options As New EdgeOptions()
    options.AddArgument("headless")
    Dim driver As IWebDriver = New EdgeDriver(driverService, options)
    

4. 重新构建干净的DLL

  • 右键VB项目→清理,然后手动删除bin和obj文件夹
  • 切换到Release配置重新构建,Debug版本的调试信息可能导致Access无法识别

5. 替代方案:通过Shell调用控制台程序

如果以上方法均无效,可以将逻辑保留为控制台程序,Access通过VBA的Shell命令调用,将结果写入临时文本文件后读取:

' Access中的VBA示例
Dim cmd As String
Dim resultPath As String
resultPath = CurrentProject.Path & "\result.txt"
cmd = """" & CurrentProject.Path & "\YourConsoleApp.exe""" & " 500000 300000 > " & resultPath
Shell cmd, vbHide
' 读取结果文件内容
Dim result As String
Open resultPath For Input As #1
Input #1, result
Close #1
Kill resultPath
MsgBox "产权费用:" & result

内容的提问来源于stack exchange,提问作者Emanuel Lerner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 14:13:14