我想编写一个 WinMerge 插件来将 SQLite 数据库转换为文本,这样我就可以使用 WinMerge 来比较数据库。
我已经用 C# 编写了代码来进行转换,但我似乎无法让它显示为 WinMerge 插件。但我对编写 COM 可见的 .NET 对象不是很熟悉。
我想我一定没有放入正确的 COM 属性(我只是将 ComVisible(true) 放在类上)。但是,我认为 VB.Net 应该为您完成所有这些工作,因此我使用 Project/Add New/COM 类重写了 VB.Net 中的类。但是,它仍然没有作为加载插件出现在 WinMerge 中。
无奈之下,我尝试使用 DLL Export Viewer 查看 VB DLL,但没有显示任何导出的函数。我显然做错了什么。
这是完整的代码:
<ComClass(WinMergeScript.ClassId, WinMergeScript.InterfaceId, WinMergeScript.EventsId)> _
Public Class WinMergeScript
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "9b9bbe1c-7b20-4826-b12e-9062fc4549a0"
Public Const InterfaceId As String = "b0f2aa59-b9d0-454a-8148-9715c83dbb71"
Public Const EventsId As String = "8f4f9c82-6ba3-4c22-8814-995ca1050de6"
#End Region
Dim _connection As SQLite.SQLiteConnection
Dim _output As IO.TextWriter
Dim _error As Long
Dim _errordesc As String
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
Public ReadOnly Property PluginEvent() As String
Get
PluginEvent = "FILE_PACK_UNPACK"
End Get
End Property
Public ReadOnly Property PluginDescription() As String
Get
PluginDescription = "Display Sqlite Databases in tab-delimited format"
End Get
End Property
Public ReadOnly Property PluginFileFilters() As String
Get
PluginFileFilters = "\.db$"
End Get
End Property
Public ReadOnly Property LastErrorNumber() As Long
Get
LastErrorNumber = _error
End Get
End Property
Public ReadOnly Property LastErrorString() As String
Get
LastErrorString = _errordesc
End Get
End Property
Public Function UnpackFile(ByVal fileSrc As String, ByVal fileDst As String, ByRef bChanged As Boolean, ByRef subcode As Long) As Boolean
On Error GoTo CleanUp
subcode = 1
_error = 0
_errordesc = ""
Using connection As New SQLite.SQLiteConnection("Data Source=" + fileSrc + ";Version=3;DateTimeFormat=ISO8601;")
_connection = connection
Using output As New IO.StreamWriter(fileDst)
_output = output
For Each table As DataRow In Query("Select name from sqlite_master where type = 'table' order by name")
Dump(table(0).ToString())
Next
End Using
End Using
bChanged = True
UnpackFile = True
Exit Function
CleanUp:
_error = Err().Number
_errordesc = Err().Description
bChanged = False
UnpackFile = False
End Function
Sub Dump(ByVal tablename As String)
Dim reader As IDataReader
Using cmd As New SQLite.SQLiteCommand(_connection)
cmd.CommandText = "Select * from """ + tablename + """"
cmd.CommandType = CommandType.Text
reader = cmd.ExecuteReader()
Using reader
_output.WriteLine("==== " + tablename + " ====")
Dim data(reader.FieldCount) As String
For i As Integer = 0 To reader.FieldCount - 1
data(i) = reader.GetName(i)
Next
Dump(data)
While reader.Read()
For i As Integer = 0 To reader.FieldCount - 1
data(i) = reader.GetValue(i).ToString()
Next
Dump(data)
End While
End Using
End Using
End Sub
Sub Dump(ByVal data() As String)
_output.WriteLine(String.Join(vbTab, data))
End Sub
Function Query(ByVal sql As String) As DataRowCollection
Dim cmd As SQLite.SQLiteCommand
cmd = _connection.CreateCommand()
Using cmd
cmd.CommandText = sql
Using da As New SQLite.SQLiteDataAdapter(cmd)
Dim dt As New DataTable()
da.Fill(dt)
Query = dt.Rows
End Using
End Using
End Function
End Class