Frage

Ich breche regelmäßig binäre Kompatibilität und benötigen eine ganze VB6-Anwendung neu kompilieren, die aus mehreren Dutzend ActiveX-DLLs und OCX insgesamt. Ich habe ein Skript geschrieben, diesen Prozess zu automatisieren, aber ich habe ein Problem festgestellt.

Wenn ein OCX mit Projektkompatibilität neu kompiliert wird seine Version erhöht wird, und Projekten, die OCX Referenzierung nicht neu kompiliert werden, bis ihre Bezugnahme auf die neue Version aktualisiert wird. Dies wird automatisch überprüft, wenn das Projekt normalerweise geöffnet ist, und der Benutzer wird aufgefordert, den Verweis zu aktualisieren, aber ich brauche es in einem Skript zu tun.

Wie kann ich es tun?

War es hilfreich?

Lösung

Ich glaube, man habe die Projektdateien (VBP), Formulardateien (FRM) und die Kontrolldateien (.ctl), die die DLLs und OCX Referenz bearbeiten und die typelib Versionsnummer erhöhen.

Sie würden neueste typelib Versionsnummer für die Steuerung / DLL in der Registrierung finden.

Dies könnte ein Schmerz sein, je nachdem, wie viele Dateien, die Sie haben.

Ein Hack wäre Hauptprojekt mit VB6 zu öffnen Ihr Skript und Schlüssel zu senden und die Referenzen aktualisieren, um zu bestätigen und speichern Sie das Projekt.

Good Luck

Andere Tipps

Ihr Projekt mehr als ein Jahrzehnt beibehalten, besteht aus einer Hierarchie von zwei Dutzenden ActiveX-DLLs und einer halben Dutzend Kontrollen. Zusammengestellt mit als auch einem Skript-System.

Ich empfehle nicht zu tun, was Sie tun.

Was wir tun, ist wie folgt

  1. Machen Sie unsere Änderungen einschließlich Ergänzungen und Test in der IDE.
  2. Wir erstellen von der Unterseite des Hierarchie nach oben
  3. kopieren wir die neu eingehalten Dateien eine Revisionsverzeichnis zum Beispiel 601, dann 602 usw. usw.
  4. Wir schaffen die setup.exe
  5. , wenn das Setup abgeschlossen ist wir kopieren über die Revision Verzeichnis in unsere Kompatibilität Direktor. beachten wir nie verweisen auf die kompilierte binäre im Projektverzeichnis. immer ein compability Verzeichnis, das alle hat die DLLs.

Der Grund, dies funktioniert, ist, dass, wenn Sie an der IDL Quelle sehen den OLE View-Tool werden Sie feststellen, dass jede referenzierte Steuerung oder DLLs an die Schnittstelle über eine # include hinzugefügt wird. Wenn Sie auf den binären in Ihrem Projektverzeichnis zeigen Sie umfassen die aus der Registrierung aufgenommen, die zu viel strangness und Kompatibilität führen kann.

Allerdings, wenn das referenzierte DLL in dem Verzeichnis vorhanden ist, dass binäre während existiert für binäre Kompatibilität verwendet wird, wird VB6, dass anstelle von was auch immer in der Registrierung.

Jetzt gibt es ein Problem, dass Sie auf einer seltenen Basis zu bekommen. Betrachten Sie diese Hierarchie

  • MyUtilityDLL
  • MyObjectDLL
  • MyUIDLL
  • MyEXE

Wenn Sie eine Eigenschaft oder eine Methode zu einer Klasse in MyUtilityDLL MyUIDLL ADD kann einen binäre Inkompatibilität Fehler nicht kompilieren geben, wenn Sie Glück haben, oder ein seltsamen Fehler wie [InRef]. In jedem Fall ist die Lösung MyUtilityDLL und dann sofort kopieren MyUtilityDLL in das Kompatibilitätsverzeichnis zu kompilieren. Dann wird der Rest des automatisierten Kompilierung wird funktionieren.

Sie können diesen Schritt in der automatisierten Build enthalten.

Beachten Sie, dass in vielen Fällen die Projekte in dem IDE gut funktionieren werden. Um, wenn Sie jetzt wissen das Sie Ihre Haare Strang ziehen könnte aus.

Wir tun ähnliche Dinge, also die Verweise auf die verwendeten OCXs direkt in VB6 VBP-Dateien zu manipulieren, in unserem VB6 Projekt Referenzen Update Tool ( hier herunterladen ) . Im Allgemeinen wird es verwendet, um die Verweise zu aktualisieren, wenn die verwendete ActiveX ihre Versionsnummern ändern, CLSIDs etc.

Die Werkzeuge ist Open Source, so dass jeder, der in diesem Problem interessiert ist, kann unsere VB-Code-Schnipsel borgen Aufgaben wie diese zu implementieren.

Unser Tool ist in Visual Basic 6 geschrieben und verwendet Tlbinf32.dll (die TypeLib Informationen DLL), die Ihnen Informationen aus Typbibliotheken programmatisch zu extrahieren.

Selbst Antwort: Ich habe einige VB6-Code geschrieben programmatisch das Upgrade zu tun. Es ist nicht ausgiebig getestet, es gibt wahrscheinlich ein paar Fehler hier und da für Eckfällen, aber ich habe es erfolgreich nutzen.

Option Explicit

Const HKEY_LOCAL_MACHINE As Long = &H80000002
Const KEY_ENUMERATE_SUB_KEYS As Long = 8
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As Any) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long

'''Returns the expected major version of a GUID if it exists, and otherwise returns the highest registered major version.
Public Function GetOcxMajorVersion(ByVal guid As String, Optional ByVal expected_version As Long) As Long
    Const BUFFER_SIZE As Long = 255
    Dim reg_key As Long
    Dim ret As Long
    Dim enum_index As Long
    Dim max_version As Long: max_version = -1

    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Classes\TypeLib\{" & guid & "}", 0, KEY_ENUMERATE_SUB_KEYS, reg_key)
    If ret <> 0 Then Err.Raise ret, , "Failed to open registry key."
    Do
        'Store next subkey name in buffer
        Dim buffer As String: buffer = Space(BUFFER_SIZE)
        Dim cur_buffer_size As Long: cur_buffer_size = BUFFER_SIZE
        ret = RegEnumKeyEx(reg_key, enum_index, buffer, cur_buffer_size, ByVal 0&, vbNullString, ByVal 0&, ByVal 0&)
        If ret <> 0 Then Exit Do
        buffer = Left(buffer, cur_buffer_size)

        'Keep most likely version
        buffer = Split(buffer, ".")(0)
        If Not buffer Like "*[!0-9A-B]*" And Len(buffer) < 4 Then
            Dim v As Long: v = CLng("&H" & buffer) 'convert from hex
            If v = expected_version Then
                max_version = v
                Exit Do
            ElseIf max_version < v Then
                max_version = v
            End If
        End If

        enum_index = enum_index + 1
    Loop
    RegCloseKey reg_key

    If max_version = -1 Then Err.Raise -1, , "Failed to enumerate any viable subkeys."
    GetOcxMajorVersion = max_version
End Function

Public Function RemoveFilename(ByVal path As String) As String
    Dim folders() As String: folders = Split(Replace(path, "/", "\"), "\")
    RemoveFilename = Left(path, Len(path) - Len(folders(UBound(folders))))
End Function

'''Changes any invalid OCX references to newer registered version
Public Sub UpdateFileOCXReferences(ByVal path As String)
    Dim file_data As String
    Dim changes_made As Boolean

    'Read
    Dim fn As Long: fn = FreeFile
    Open path For Input As fn
        While Not EOF(fn)
            Dim line As String
            Line Input #fn, line

            'check for ocx reference line
            If LCase(line) Like "object*=*{*-*-*-*-*}[#]*#.#*[#]#*;*.ocx*" Then
                'get guid
                Dim guid_start As Long: guid_start = InStr(line, "{") + 1
                Dim guid_end As Long: guid_end = InStr(line, "}")
                Dim guid As String: guid = Mid(line, guid_start, guid_end - guid_start)

                'get reference major version
                Dim version_start As Long: version_start = InStr(line, "#") + 1
                Dim version_end As Long: version_end = InStr(version_start + 1, line, ".")
                Dim version_text As String: version_text = Mid(line, version_start, version_end - version_start)

                'play it safe
                If Len(guid) <> 32 + 4 Then Err.Raise -1, , "GUID has unexpected length."
                If Len(version_text) > 4 Then Err.Raise -1, , "Major version is larger than expected."
                If guid Like "*[!0-9A-F-]*" Then Err.Raise -1, , "GUID has unexpected characters."
                If version_text Like "*[!0-9]*" Then Err.Raise -1, , "Major version isn't an integer."

                'get registry major version
                Dim ref_version As Long: ref_version = CLng(version_text)
                Dim reg_version As Long: reg_version = GetOcxMajorVersion(guid, ref_version)

                'change line if necessary
                If reg_version < ref_version Then
                    Err.Raise -1, , "Registered version precedes referenced version."
                ElseIf reg_version > ref_version Then
                    line = Left(line, version_start - 1) & CStr(reg_version) & Mid(line, version_end)
                    changes_made = True
                End If
            End If

            file_data = file_data & line & vbNewLine
        Wend
    Close fn

    'Write
    If changes_made Then
        Kill path
        Open path For Binary As fn
            Put fn, , file_data
        Close fn
    End If
End Sub

'''Changes any invalid in included files to newer registered version
Public Sub UpdateSubFileOCXReferences(ByVal path As String)
    Dim folder As String: folder = RemoveFilename(path)
    Dim fn As Long: fn = FreeFile
    Open path For Input As fn
        While Not EOF(fn)
            Dim line As String
            Line Input #fn, line

            If LCase(line) Like "form=*.frm" _
                            Or LCase(line) Like "usercontrol=*.ctl" Then
                Dim file As String: file = folder & Mid(line, InStr(line, "=") + 1)
                If Dir(file) <> "" Then
                    UpdateFileOCXReferences file
                End If
            End If
        Wend
    Close fn
End Sub
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top