2012-10-23 14 views
5

मैं पाठ में SQLite डेटाबेस का अनुवाद करने में एक WinMerge प्लगइन लिखने के लिए चाहते हैं में एक WinMerge प्लगइन लिखने के लिए कैसे, तो मैं डेटाबेस की तुलना करने के लिए WinMerge उपयोग कर सकते हैं।सी # (या VB.NET)

मैं सी # में कोड लिखा है रूपांतरण करने के लिए, लेकिन मैं इसे एक WinMerge प्लगइन के रूप में प्रदर्शित करने के लिए नहीं कर पा रहे। लेकिन मैं COM-visible .NET ऑब्जेक्ट्स लिखने से बहुत परिचित नहीं हूं।

मैं लगा मैं सही कॉम विशेषताओं में डाल दिया है नहीं होना चाहिए (मैं सिर्फ ComVisible (सही) वर्ग पर डाल)। हालांकि, मुझे लगता है कि वीबी.Net को आपके लिए वह सब कुछ करना है, इसलिए मैं परियोजना/नई/COM कक्षा का उपयोग करके, VB.Net में कक्षा को फिर से लिखता हूं। हालांकि, यह अभी भी एक लोड प्लगइन के रूप में WinMerge में दिखाई नहीं देता है।

हताशा में, मैं वीबी DLL 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 

उत्तर

1

मैं बस अब WinMerge 2.14.0 की वास्तविक कोड की समीक्षा की है, और मैं इसे केवल वास्तविक COM DLLs (और OCXs) के लिए काम करता है, जिसका मुख्य कारण लगता है यह COM वस्तुओं को पंजीकृत होने की अपेक्षा किए बिना काम करता है। इसे कम से कम संदर्भित करने के लिए विस्तारित करने की आवश्यकता होगी। टीएलबी या किसी पथ को निर्दिष्ट करने की अनुमति देने के लिए समायोजित, लेकिन "WinMergeScript" से अधिक स्पष्ट आईडी।


एक काम VB.NET COM वस्तु में मैं स्पष्ट रूप से <ComVisible(True)> _ उल्लेख और प्रोजेक्ट को संकलित गुण में जाँच "कॉम के लिए रजिस्टर" किया है।

मैंने अभी आपके कोड का उपयोग करके HelloWorld फ़ंक्शन बनाया है, इसे vbc /t:library के साथ संकलित किया है और इसे regasm /codebase के साथ पंजीकृत किया है।

Option Explicit 
Dim so 
Set so = CreateObject("SO13035027.WinMergeScript") 
MsgBox so.HelloWorld 

और सारी कोड (मैं एक बाद vbc तो यह वास्तव में .NET 1.1 के लिए संकलित किया गया उपयोग करने के लिए अपने सिस्टम को पुन: कॉन्फ़िगर नहीं किया है):

यह सफलतापूर्वक इस सरल VBScript का उपयोग कर बुलाया गया था ( wscript का प्रयोग करके)
Option Explicit On 
Option Strict On 
'Option Infer On 

Imports Microsoft.VisualBasic 

Namespace SO13035027 
<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-9062fc4549a2" 
Public Const InterfaceId As String = "b0f2aa59-b9d0-454a-8148-9715c83dbb72" 
Public Const EventsId As String = "8f4f9c82-6ba3-4c22-8814-995ca1050de2" 
#End Region 

' 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 Function HelloWorld() As String 
Return "Hello, world!" 
End Function 

End Class 
End Namespace 
+0

धन्यवाद - मैं " _" को शामिल किया है WinMergeScript कक्षा के सामने, और प्रत्येक सार्वजनिक समारोह के सामने। मैंने पहले से ही असेंबली इन्फ्लो संवाद में "असेंबली COM-Visible" बना लिया था, परियोजना प्रॉपर्टीज, एप्लिकेशन, असेंबली इन्फो बटन से पहुंचा था। मुझे कहीं भी "COM के लिए रजिस्टर" नहीं मिल रहा है (विजुअल स्टूडियो 2008)। अभी भी काम नहीं करता है, और डीएलएल दर्शक संकलित डीएलएल में कोई COM ऑब्जेक्ट्स या विधियों को नहीं दिखाता है। –

+0

[बाद में] मैंने प्रोजेक्ट संकलन विकल्पों में "COM इंटरऑप के लिए पंजीकरण" पाया है, और यह पहले से ही टिकाया गया था। –

+0

क्या आप इसे कभी काम करने के लिए मिला? यदि हाँ: क्या आप इसे साझा कर सकते हैं? – fabsenet