将 .Net dll 嵌入到 Microsoft Access 数据库中
Embed .Net dll into Microsoft Access Database
1) 是否可以将 .net dll 嵌入到 Microsoft Access 数据库中?理想情况下,我希望 dll 实际上嵌入到访问数据库中,因此它不会丢失。我需要从我的访问数据库中访问一些 API。
2) 如果可以,有什么限制?我假设访问数据库必须在安装了 .net 的机器上使用。还有其他我应该考虑的问题吗?
如果我没看错的话,这实际上似乎是 2 个与所问问题略有不同的问题:(1) 你能在 JET/ACE 数据库中嵌入一个二进制文件吗?和 (2) 您可以从 MS-Access 的 .NET DLL 调用方法吗?
- 是的,您可以将二进制文件嵌入到 JET/ACE 数据库中。我的首选方法是在 Memo 字段中将文件读取为二进制文件并编码为 base64。
首先,您需要将二进制文件读入字节数组。这可以使用 Open
或使用 ADODB.Stream
对象来完成。然后,将字节数组编码为 Base64 字符串,最后将该字符串写入 table。要导出二进制文件,您需要执行相反的操作。
以下是将字节数组转换为 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 也有一个 "Attachment" 字段。我相信可以使用它。
- 是的,可以从 .NET DLL 调用方法 - 请参阅 here。您实际上在做的是在 Access 中托管 .NET 运行时。
限制是您只能托管 .NET 2.0 或 3.5 运行时——尽管链接页面说您可以使用 4.0。据我所知,没有简单的方法可以在 VBA 中托管 .NET 4.0+ 运行时。如果您尝试调用 4.0+ DLL,您将收到 "the assembly is newer than the runtime".
效果的错误
是的,您还需要在安装了 2.0 and/or 3.5 运行时的机器上使用它。
此外,它不会直接从网络共享加载 DLL。这是 .NET 框架的限制,可以克服 (link),但我不确定在 Access 中托管 DLL 时是否可以做到这一点。
为了使用"embedded" DLL,在使用前需要从数据库中导出;一个好的地方是用户的临时文件夹。
编辑: 关于第 (2) 点——我之前曾写过,您不需要将 C# class 公开为 COM,但是,在测试之后我意识到这是不正确的。您确实需要使用 [COMVisible(true)]
属性声明 class(或实现 IDispatch 接口),以便 VBA 正确实例化您的 class-- 否则 CreateInstanceFrom
将 return 没有。
1) 是否可以将 .net dll 嵌入到 Microsoft Access 数据库中?理想情况下,我希望 dll 实际上嵌入到访问数据库中,因此它不会丢失。我需要从我的访问数据库中访问一些 API。
2) 如果可以,有什么限制?我假设访问数据库必须在安装了 .net 的机器上使用。还有其他我应该考虑的问题吗?
如果我没看错的话,这实际上似乎是 2 个与所问问题略有不同的问题:(1) 你能在 JET/ACE 数据库中嵌入一个二进制文件吗?和 (2) 您可以从 MS-Access 的 .NET DLL 调用方法吗?
- 是的,您可以将二进制文件嵌入到 JET/ACE 数据库中。我的首选方法是在 Memo 字段中将文件读取为二进制文件并编码为 base64。
首先,您需要将二进制文件读入字节数组。这可以使用 Open
或使用 ADODB.Stream
对象来完成。然后,将字节数组编码为 Base64 字符串,最后将该字符串写入 table。要导出二进制文件,您需要执行相反的操作。
以下是将字节数组转换为 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 也有一个 "Attachment" 字段。我相信可以使用它。
- 是的,可以从 .NET DLL 调用方法 - 请参阅 here。您实际上在做的是在 Access 中托管 .NET 运行时。
限制是您只能托管 .NET 2.0 或 3.5 运行时——尽管链接页面说您可以使用 4.0。据我所知,没有简单的方法可以在 VBA 中托管 .NET 4.0+ 运行时。如果您尝试调用 4.0+ DLL,您将收到 "the assembly is newer than the runtime".
效果的错误是的,您还需要在安装了 2.0 and/or 3.5 运行时的机器上使用它。
此外,它不会直接从网络共享加载 DLL。这是 .NET 框架的限制,可以克服 (link),但我不确定在 Access 中托管 DLL 时是否可以做到这一点。
为了使用"embedded" DLL,在使用前需要从数据库中导出;一个好的地方是用户的临时文件夹。
编辑: 关于第 (2) 点——我之前曾写过,您不需要将 C# class 公开为 COM,但是,在测试之后我意识到这是不正确的。您确实需要使用 [COMVisible(true)]
属性声明 class(或实现 IDispatch 接口),以便 VBA 正确实例化您的 class-- 否则 CreateInstanceFrom
将 return 没有。