1)是否可以将.net dll嵌入到Microsoft Access数据库中?理想情况下,我希望dll实际嵌入到访问数据库中,因此它不会丢失。我需要从访问数据库中访问一些API。
2)如果可能,有什么限制?我假设访问数据库必须在安装了.net的计算机上使用。我还应该考虑其他问题吗?
答案 0 :(得分:6)
如果我正确地阅读它,这实际上似乎是两个稍微不同的问题:(1)你能在JET / ACE数据库中嵌入二进制文件吗? (2)你能从MS-Access调用.NET DLL中的方法吗?
首先,您需要将二进制文件读入一个字节数组。这可以使用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也有一个"附件"领域。我相信可以使用它。
限制是你只能托管.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。