将.Net dll嵌入Microsoft Access数据库

时间:2015-02-05 19:07:34

标签: c# ms-access dll

1)是否可以将.net dll嵌入到Microsoft Access数据库中?理想情况下,我希望dll实际嵌入到访问数据库中,因此它不会丢失。我需要从访问数据库中访问一些API。

2)如果可能,有什么限制?我假设访问数据库必须在安装了.net的计算机上使用。我还应该考虑其他问题吗?

1 个答案:

答案 0 :(得分:6)

如果我正确地阅读它,这实际上似乎是两个稍微不同的问题:(1)你能在JET / ACE数据库中嵌入二进制文件吗? (2)你能从MS-Access调用.NET DLL中的方法吗?

  1. 是的,您可以在JET / ACE数据库中嵌入二进制文件。我这样做的首选方法是在备注字段中将文件读取为二进制文件并编码为base64。
  2. 首先,您需要将二进制文件读入一个字节数组。这可以使用Open或使用ADODB.Stream对象来完成。然后,将字节数组编码为Base64字符串,最后,将该字符串写入表中。要导出二进制文件,请执行相反的操作。

    以下是将字节数组转换为Base 64(Source)的函数:

    'Requires reference to Microsoft XML v3.0
    Private Function EncodeBase64(ByRef arrData() As Byte) As String
    
        Dim objXML As MSXML2.DOMDocument
        Dim objNode As MSXML2.IXMLDOMElement
    
        ' help from MSXML
        Set objXML = New MSXML2.DOMDocument
    
        ' byte array to base64
        Set objNode = objXML.createElement("b64")
        objNode.dataType = "bin.base64"
        objNode.nodeTypedValue = arrData
        EncodeBase64 = objNode.Text
    
        ' thanks, bye
        Set objNode = Nothing
        Set objXML = Nothing
    
    End Function
    
    Private Function DecodeBase64(ByVal strData As String) As Byte()
    
        Dim objXML As MSXML2.DOMDocument
        Dim objNode As MSXML2.IXMLDOMElement
    
        ' help from MSXML
        Set objXML = New MSXML2.DOMDocument
        Set objNode = objXML.createElement("b64")
        objNode.dataType = "bin.base64"
        objNode.Text = strData
        DecodeBase64 = objNode.nodeTypedValue
    
        ' thanks, bye
        Set objNode = Nothing
        Set objXML = Nothing
    
    End Function
    

    以下是如何使用这些Base64函数使用ADODB.Stream对象将二进制文件导入和导出到备注字段中的示例:

    Function ImportBinary()
        'Requires a reference to ActiveX Data Objects 2.8 or higher
        Dim InputStream As ADODB.stream
        Dim FileBytes() As Byte
    
        Set InputStream = New ADODB.stream
        InputStream.Type = adTypeBinary
        InputStream.Open
        InputStream.LoadFromFile ("A:\Binary\File\To\Import.dll")
        FileBytes = InputStream.Read()
    
        With CurrentDb().TableDefs("TableWithMemoField").OpenRecordset
            .AddNew
            !MemoField.Value = EncodeBase64(FileBytes)
            .Update
            .Close
        End With
    
        InputStream.Close
    End Function
    
    Function ExportBinary()
        Dim OutputStream As ADODB.stream
    
        Set OutputStream = New ADODB.stream
        OutputStream.Type = adTypeBinary
        OutputStream.Open
    
        With CurrentDb().TableDefs("TableWithMemoField").OpenRecordset
            OutputStream.Write DecodeBase64(!MemoField.Value)
            .Close
        End With
    
        OutputStream.SaveToFile "A:\Binary\File\To\Export.dll"
    
        OutputStream.Close
    End Function
    

    或者,您也可以将文件嵌入到OLE字段中,或者,最新版本的Access也有一个"附件"领域。我相信可以使用它。

    1. 是的,可以从.NET DLL中调用方法 - 请参阅here。您实际上在做的是在Access中托管.NET运行时。
    2. 限制是你只能托管.NET 2.0或3.5运行时 - 尽管链接页面说你可以使用4.0。据我所知,没有简单的方法可以在VBA中托管.NET 4.0+运行时。如果你试图调用一个4.0+ DLL,你会得到一个错误,#34;组件比运行时更新"。

      是的,您还需要在安装了2.0和/或3.5运行时的计算机上使用它。

      此外,它不会直接从网络共享加载DLL。这是.NET框架的一个限制,它可以克服(link),但我不确定在Access中托管DLL时是否可以这样做。

      为了使用" embedded" DLL,你需要在使用之前从数据库中导出它;一个好地方就是用户的临时文件夹。

      编辑:关于第(2)点 - 我之前写过你不需要将你的C#类暴露为COM,但是,经过测试,我意识到这是不正确的。您需要使用[COMVisible(true)]属性声明您的类(或实现IDispatch接口),以便VBA正确实例化您的类 - 否则CreateInstanceFrom将返回Nothing。