Übersetzen von VB6 zu .NET Code - Benutzung von Funktionen

  • VB.NET

Es gibt 28 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    Übersetzen von VB6 zu .NET Code - Benutzung von Funktionen

    Hi,

    ich versuche gerade einen offensichtlich in VB6 geschriebenen Code in .NET umzuschreiben. Dabei stosse ich auf folgendes Problem. Mein Editor scheint folgende Codezeile nicht zu akzeptieren und unterstreicht diese rot. Dabei ist das wie im Lehrbuch (oder ich übersehe da etwas):

    VB.NET-Quellcode

    1. Public Function MP3_ID3v2Exists(ByVal sFile As String) As Long


    Auch wenn ich das ByVal weglasse meckert er...

    Ausserdem folgende Zeile in der Funktion:

    Visual Basic-Quellcode

    1. MP3_ID3v2Exists = 0
    2. Exit Function


    wird zwar akzeptiert aber das sollte doch eigentlich so sein:

    VB.NET-Quellcode

    1. Return 0


    Oder wird sonst die Funktion nicht beendet?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    kafffee schrieb:

    Auch wenn ich das ByVal weglasse meckert er...
    Die Alternative wäre ByRef, hier aber falsch.
    Dies wäre völlig korrekt:

    VB.NET-Quellcode

    1. Public Function MP3_ID3v2Exists(sFile As String) As Long
    2. ' ...
    3. Return 0
    4. End Function
    MP3_ID3v2Exists = 0 ist alte VB6-Syntax, da wurde dem Prozedur-Namen der Returnwert zugewiesen.
    Zu überprüfen wäre, ob der Typ der Funktion auf Integer geändert werden kann.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Schon wieder so was unerklärliches... ?(

    RodFromGermany schrieb:

    Zu überprüfen wäre, ob der Typ der Funktion auf Integer geändert werden kann.


    Ja das hab ich mir auch schon gedacht. Zurückgegeben wird der Wert 0 bei einem Fehler oder wenn die *.mp3-Datei kein ID3v2-Tag besitzt.

    Andernfalls die Länge des ID3v2-Tags...

    Wäre mal auszuprobieren aber das sollte doch eigentlich ein Integer sein...

    kafffee schrieb:

    Andernfalls die Länge des ID3v2-Tags...
    Wenn ich hier reinsehe:
    de.wikipedia.org/wiki/ID3-Tag
    genügt ein Integer.
    Die Aussage
    VB6 Long ---> VB.net Integer
    VB6 Integer ---> Vb.net Short
    allein ist da doch etwas zu pauschal.
    Bei der Übertragung der Deklaration von API-Funktionen hingegen essentiell.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Weiter im (Quell)Text...

    hab jetzt den auskommentierten Text umgeschrieben, oder versucht umzuschreiben:

    VB.NET-Quellcode

    1. 'Größe des ID3v2-Tags ermitteln
    2. 'F = FreeFile()
    3. 'Open sFile For Binary As #F
    4. 'Get #F, 7, b(4)
    5. 'Get #F, 8, b(3)
    6. 'Get #F, 9, b(2)
    7. 'Get #F, 10, b(1)
    8. Dim length = 1
    9. Dim bnr() As Byte = New Byte(length - 1) {}
    10. Using fs = New System.IO.FileStream(sFile, IO.FileMode.Open)
    11. fs.Read(bnr(1), 7, length)
    12. fs.Read(bnr(2), 8, length)
    13. fs.Read(bnr(3), 9, length)
    14. fs.Read(bnr(4), 10, length)
    15. End Using


    Aber es kommt wieder zu rot unterstrichenem bnr(1) bis bnr(4) in den Zeilen 12-15

    Edit: Oder so, aber dann kommt der Fehler "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection":

    VB.NET-Quellcode

    1. ​Dim length = 4
    2. Dim bnr() As Byte = New Byte(length - 1) {}
    3. Using fs = New System.IO.FileStream("test.mp3", IO.FileMode.Open)
    4. fs.Read(bnr, 7, length)
    5. End Using

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    naja, schau in der Dokumentation von FileStream.Read() nach, was die Methode tut, und v.a., welche Argumente sie erwartet - und was sie zurückgibt (Es ist ja eine Function).
    Gib ihr die richtigen Argumente, und die roten Kringel gehen weg.
    MIt "richtig" ist vor allem der richtige Datetyp der Argumente gemeint.
    @kafffee Wenn das dieses Tag sein soll, kannstz Du auch gleich ein Integer auslesen, vorausgesetzt, die ByteOrder ist korrekt.
    Vielleicht postest Du zumindest die komplette Prozedur, das wird besser, schneller und richtiger als häppchenweise ein paar Code-Zeilen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hier ist der Code. Die "alten" Zeilen hab ich auskommentiert:

    VB.NET-Quellcode

    1. Public Function MP3_ID3v2Exists(sFile As String) As Integer
    2. Dim sText As String
    3. Dim sBin As String
    4. Dim sID3 As String * 3 'ACHTUNG EDIT: Was das zu bedeuten hat wüsste ich auch gerne. Ich hab das zuerst für einen Tippfehler gehalten und das [tt]* 3[/tt] einfach rausgelöscht...
    5. Dim i As Integer
    6. Dim z As Integer
    7. 'Dim bnr(4) As Byte
    8. Dim F As Integer
    9. Dim nID3v2Size As Integer
    10. ' Datei öffnen
    11. On Error GoTo ErrHandler
    12. 'F = FreeFile()
    13. 'Open sFile For Binary As #F
    14. 'Get #F, 1, sID3
    15. Dim by() As Byte = New Byte(2) {}
    16. Using fs = New System.IO.FileStream(sFile, IO.FileMode.Open)
    17. fs.Read(by, 0, 3)
    18. End Using
    19. sID3 = System.Text.Encoding.Default.GetString(by)
    20. If sID3 <> "ID3" Then
    21. Return 0
    22. End If
    23. 'Größe des ID3v2-Tags ermitteln
    24. 'F = FreeFile()
    25. 'Open sFile For Binary As #F
    26. 'Get #F, 7, b(4)
    27. 'Get #F, 8, b(3)
    28. 'Get #F, 9, b(2)
    29. 'Get #F, 10, b(1)
    30. Dim length = 4
    31. Dim bnr() As Byte = New Byte(length - 1) {}
    32. Using fs = New System.IO.FileStream(sFile, IO.FileMode.Open)
    33. fs.Read(bnr, 7, length)
    34. End Using
    35. sBin = ""
    36. For z = 2 To 4
    37. For i = 0 To 6
    38. sBin = sBin & CStr(Math.Abs(b(z) And (2 ^ i)))
    39. Next i
    40. Next z
    41. nID3v2Size = 0
    42. For i = 7 To 27
    43. nID3v2Size = nID3v2Size + ((2 ^ i) *
    44. Val(Mid(sBin, i - 6, 1)))
    45. Next i
    46. nID3v2Size = nID3v2Size + b(1) + 10
    47. Return nID3v2Size
    48. ' Close #F
    49. Exit Function
    50. ErrHandler:
    51. ' If F > 0 Then Close #F
    52. Return 0
    53. End Function

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    @kafffee Probier mal

    VB.NET-Quellcode

    1. Public Function MP3_ID3v2Exists(sFile As String) As Integer
    2. Dim by() As Byte = New Byte(2) {}
    3. Using fs = New System.IO.FileStream(sFile, IO.FileMode.Open)
    4. fs.Read(by, 0, 3)
    5. End Using
    6. Dim sID3 = System.Text.Encoding.Default.GetString(by)
    7. If sID3 <> "ID3" Then
    8. Return 0
    9. End If
    10. 'Größe des ID3v2-Tags ermitteln
    11. Dim length = 4
    12. Dim bnr() As Byte = New Byte(length - 1) {}
    13. Using fs = New System.IO.FileStream(sFile, IO.FileMode.Open)
    14. fs.Read(bnr, 0, length)
    15. End Using
    16. Return BitConverter.ToInt32(bnr, 0) ' + 10 ' ???
    17. End Function
    In Zeile 17 das + 10 sieht merkwürdig aus, kommt aber da vor.
    Probiere es einfach mal aus.
    Ansonsten kann noch die Reihenfolge im Byte-Array geändert werden (von hinten nach vorn).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja er spuckt mir eine Zahl aus. Ob das die richtige ist weiss ich nicht keine Ahnung wie gross das ID3-Tag ist.

    Das müsste man mit dieser Funktion testen. Wär gut wenn du da mal dein Glück versuchst ich seh da den Wald vor lauter Bäumen nicht..

    VB.NET-Quellcode

    1. ' ID3v2-Infos auslesen
    2. Public Function MP3_ReadID3v2Tag(ByVal sFile As String, ByVal nID3v2Size As Long) As ID3v2
    3. Dim nPos As Long
    4. Dim sFrameType As String * 4 'was das hier macht wüsste ich auch nur zu gerne
    5. Dim sText As String
    6. Dim sBin As String
    7. Dim sID3 As String * 3 'und das
    8. Dim i As Integer
    9. Dim z As Integer
    10. Dim b(4) As Byte
    11. Dim F As Integer
    12. Dim nSize As Long
    13. On Error GoTo ErrHandler
    14. ' Datei öffnen
    15. F = FreeFile()
    16. Open sFile For Binary As #F
    17. ' Start-Position
    18. nPos = 11
    19. ' Liest den Framtyp so lange aus bis es nichts
    20. ' mehr zum lesen gibt
    21. Do While nPos < nID3v2Size
    22. ' der eingelesene Framtyp
    23. Get #F, nPos, sFrameType
    24. If InStr(sFrameType, Chr$(0)) > 0 Then
    25. ' Fertig nichts mehr zum lesen
    26. Close #F
    27. Exit Do
    28. End If
    29. nPos = nPos + 4
    30. Get #F, nPos, b(4) ' FrameTyp Größe
    31. Get #F, nPos + 1, b(3) ' FrameTyp Größe
    32. Get #F, nPos + 2, b(2) ' FrameTyp Größe
    33. Get #F, nPos + 3, b(1) ' FrameTyp Größe
    34. nPos = nPos + 5
    35. sBin = ""
    36. For z = 2 To 4
    37. For i = 0 To 7 Step 1
    38. sBin = sBin & CStr(Math.Abs(b(z) And (2 ^ i)))
    39. Next i
    40. Next z
    41. ' Framtyp-Größe ausrechnen
    42. nSize = 0
    43. For i = 8 To 30
    44. nSize = nSize + ((2 ^ i) * Val(Mid$(sBin, i - 7, 1)))
    45. Next i
    46. nSize = nSize + b(1)
    47. ' ID3v2-Info
    48. sText = String$(nSize, vbNullChar) 'und zu dem hab ich bei Google keinen .NET-Ersatz gefunden, vielleicht einfach CStr()??
    49. nPos = nPos + 1
    50. Get #F, nPos, sText
    51. sText = TrimNullChar(sText)
    52. With MP3_ReadID3v2Tag
    53. Select Case sFrameType
    54. Case "TMED"
    55. .sMedium = sText
    56. '[...] usw.
    57. End Select
    58. nPos = nPos + nSize
    59. End With
    60. Loop
    61. ErrHandler:
    62. Close #F
    63. End Function
    Boah, nee. Keine On Error-Geschichten mehr in VB.NET! Arbeite (richtig) mit Try-Catch. Aber: Fange nur Exceptions ab, die Du kennst und sinnvoll bearbeiten kannst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Ja hatte ich eh vor aber danke. :) Das Beste zum Schluss...

    @RodFromGermany
    Was mich bei deinem Code in Post 10 etwas verwirrt ist dass du die Bytes scheinbar ab Position 0 einliest. Es müssten doch die Bytes 7, 8 ,9, 10 sein sehe ich das richtig? Bloss wenn ich fs.Read(bnr, 7, length) mache, kommt dieser Fehler "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection":"

    Sonst liest der computer doch die falschen Bytes aus, der weiss ja nicht dass wir die Länge des Tags aus der Datei lesen wollen...

    Oder bin ich da auf dem falschen Dampfer?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    kafffee schrieb:

    Oder bin ich da auf dem falschen Dampfer?
    Das sagte ich im Grunde bereits in post#7.
    Ich bin auch höchst unsicher, ob RFGs Code zielführend ist.
    Schon dass da in derselben Methode die Datei zweimal geöffnet, gelesen geschlossen wird ist mir höchst verdächtig. Und scheints auch nur am Anfang der Datei. Dabei dachte ich, die Id3v2Tags seien am Ende der Datei zu finden. Und es bringt ja auch nicht viel zu erfahren, ob eine Datei getaggt ist - sondern, wenn man sie schon aufmacht und liest, dann sollte man die Daten doch auch gleich auslesen - dass sie nicht noch ein drittes Mal geöffnet werden muss für was eigentlich ein Fliegenschiss sein sollte.
    Imo muss eine .Net-Klasse her, die eine Id4vDingens-getaggte Datei repräsentiert.
    Beim Erstellen eines Objekts davon wird der Dateiname angegeben, und dann liest das Ding eben die "Tag-Zone" aus und weiss bescheid.
    Wie gesagt: solche Tag-Wrapper-Klassen sollten sich eigentlich im INet finden lassen - imo seid ihr voll dabei das Rad neu zu erfinden.
    Hab mich mal umgeschaut und tatsächlich was gefunden:

    (1) mp3class --> kann man eine *.exe runterladen aber da meckert mein Virenscanner
    (2) id3.NET (zu finden auf sourceforge.net) --> ist ein *.zip mit mehreren *.dll und *.pdb-Dateien drin, aber keine Ahnung wie ich das installieren soll bzw. dann in mein Projekt einfügen...

    Meine Vermutung:
    Alles nach C:\Windows\System kopieren.
    Mit regsvr32 C:\Windows\System32\Test.dll registrieren
    Verweis in VS2019 hinzufügen

    Oder gibts das auch automatisiert in VS? Mir ist das ein wenig heikel..

    Da steht auch es ist geeignet für .NET Framework, ich kann es also mit VB.NET benutzen??

    Wenn ihr wollt kann ich das ZIP-File mal anhängen..
    Was haltet ihr davon? Hab mich mal bissle ins Zeug gelegt. Das sieht schon besser aus oder?:

    VB.NET-Quellcode

    1. Dim baits As Byte() = My.Computer.FileSystem.ReadAllBytes("test.mp3")
    2. sID3 = System.Text.Encoding.Default.GetString(baits, 0, 3)
    3. If sID3 <> "ID3" Then
    4. Return 0
    5. End If
    6. 'Größe des ID3v2-Tags ermitteln
    7. 'F = FreeFile()
    8. 'Open sFile For Binary As #F
    9. 'Get #F, 7, b(4)
    10. 'Get #F, 8, b(3)
    11. 'Get #F, 9, b(2)
    12. 'Get #F, 10, b(1)
    13. Dim bnr() As Byte
    14. bnr(1) = baits(10)
    15. bnr(2) = baits(9)
    16. bnr(3) = baits(8)
    17. bnr(4) = baits(7)
    18. Return BitConverter.ToInt32(bnr, 1) + 10 'hier bin ich mir unsicher ob Index 0 oder 1 und ob das "BitConverter.ToInt32" notwendig ist bzw. was es macht (irgendein Typ umwandeln oder?


    @ErfinderDesRades


    Ja hab tatsächlich was gefunden. Aber nur für WMA-Files. Aber das werd ich in mein Projekt integrieren, kann nicht schaden,,,

    Für ID3v2 Tags hab ich auch was gefunden aber das ist in C#. Und alles was mit C zu tun hat ist für mich bissle ein rotes Tuch ?(

    Jetzt muss ich erstmal klarkommen mit VB. Daher wäre es nicht schlecht wenn wir das was wir ursprünglich erarbeitet haben in diesem Thread auch fertigstellen könnten. Jetzt haben wir auch so viel Arbeit da schon reingesteckt. Wäre schade um die Zeit, obwohl ich einiges gelernt hab...

    ID3v1 wäre kein Problem da hab ich schon was gefunden, aber meine Musiksammlung ist vorwiegend mit ID3v2 ausgestattet. Aber du hast Recht. Die v1-Tags sind am Dateianfang angebracht, die v2-Tags am Ende wenn ich das so richtig gelesen hab...

    Einfach so eine fertige DLL zu benutzen find ich bissle heikel...

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kafffee“ ()

    Und analog dazu:

    VB.NET-Quellcode

    1. 'ID3v2-Infos auslesen
    2. Public Function MP3_ReadID3v2Tag(ByVal sFile As String, ByVal nID3v2Size As Long) As ID3v2
    3. Dim nPos As Long
    4. Dim sFrameType As String * 4 'hier brauche ich noch etwas Hilfe
    5. Dim sText As String
    6. Dim sBin As String
    7. Dim sID3 As String * 3 'und hier
    8. Dim i As Integer
    9. Dim z As Integer
    10. Dim b(4) As Byte
    11. Dim F As Integer
    12. Dim nSize As Long
    13. On Error GoTo ErrHandler 'das machen wir zum Schluss :-)
    14. ' Datei öffnen
    15. 'F = FreeFile()
    16. 'Open sFile For Binary As #F
    17. Dim baits As Byte() = My.Computer.FileSystem.ReadAllBytes("test.mp3")
    18. ' Start-Position
    19. nPos = 11
    20. ' Liest den Framtyp so lange aus bis es nichts
    21. ' mehr zum lesen gibt
    22. Do While nPos < nID3v2Size
    23. ' der eingelesene Framtyp
    24. 'Get #F, nPos, sFrameType
    25. baits(nPos) = sFrameType
    26. If InStr(sFrameType, Chr$(0)) > 0 Then 'hier brauche ich auch noch bissle Hilfe
    27. ' Fertig nichts mehr zum lesen
    28. 'Close #F
    29. Exit Do
    30. 'End If
    31. nPos = nPos + 4
    32. 'Get #F, nPos, b(4) ' FrameTyp Größe
    33. 'Get #F, nPos + 1, b(3) ' FrameTyp Größe
    34. 'Get #F, nPos + 2, b(2) ' FrameTyp Größe
    35. 'Get #F, nPos + 3, b(1) ' FrameTyp Größe
    36. 'nPos = nPos + 5
    37. b(4) = baits(nPos)
    38. b(3) = baits(nPos + 1)
    39. b(2) = baits(nPos + 2)
    40. b(1) = baits(nPos + 3)
    41. nPos = nPos + 5
    42. sBin = ""
    43. For z = 2 To 4
    44. For i = 0 To 7 Step 1
    45. sBin = sBin & CStr(Math.Abs(b(z) And (2 ^ i)))
    46. Next i
    47. Next z
    48. ' Framtyp-Größe ausrechnen
    49. nSize = 0
    50. For i = 8 To 30
    51. nSize = nSize + ((2 ^ i) * Val(Mid$(sBin, i - 7, 1))) 'und hier natürlich
    52. Next i
    53. nSize = nSize + b(1)
    54. ' ID3v2-Info
    55. sText = String$(nSize, vbNullChar) 'und hier auch
    56. nPos = nPos + 1
    57. 'Get #F, nPos, sText
    58. sText = baits(nPos)
    59. sText = TrimNullChar(sText)
    60. With MP3_ReadID3v2Tag
    61. ' Select Case sFrameType
    62. Case "TMED"
    63. .sMedium = sText
    64. Case "TLEN"
    65. .sLen = sText
    66. [...]
    67. End Function

    kafffee schrieb:

    Es müssten doch die Bytes 7, 8 ,9, 10 sein sehe ich das richtig?
    Das sind die so genannten Magic Bytes.
    Wenn ich mir eine MP3 ansehe, stehen die an Position 0, mein Code ist also richtig:

    ====
    Die Exception, die Du meinst, ist Ursache eines falsch verstandenen Parameters, der gibt den Offset im Byte-Array an, wo hingeschrieben werden soll:
    docs.microsoft.com/de-de/dotne…estream.read?view=net-5.0
    Wenn Du das 7. Byte lesen willst, musst Du den Lese-Zeiger auf Position 7 des Streams platzieren, das geht mit FileStream.Seek()
    docs.microsoft.com/de-de/dotne…estream.seek?view=net-5.0
    und das müsste dann für die Position des Tags getan werden:

    VB.NET-Quellcode

    1. fs.Seek(DEINE_POSITION, IO.SeekOrigin.Begin)

    maniactools.de/soft/mp3tag-pro…ags-versionen-von-id3.htm
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „RodFromGermany“ ()

    Also wie kommst du denn auf diese "Magic Bytes"? Im Internet steht ja viel wenn der Tag lang ist. Die ersten drei Bytes waren doch schon für den String "ID3" reserviert. Siehe Post #17 Zeile 2-4. Und auf deinem Bild in Post #19 sieht man das doch auch ganz oben rechts? Also kann das ja gar nicht bei Null anfangen oder?

    Guck mal hier da ist das Format sehr ausführlich beschrieben:

    mutagen-specs.readthedocs.io/e…/id3v2.4.0-structure.html

    Da steht u.a. für den Header:

    The first part of the ID3v2 tag is the 10 byte tag header, laid out as follows:

    ID3v2/file identifier: "ID3"
    ID3v2 version: $04 00
    ID3v2 flags: %abcd0000
    ID3v2 size: 4 * %0xxxxxxx


    Ich würde es ja einfach ausprobieren, aber das Programm läuft noch nicht, wegen den Zeilen, die ich in Post #18 auskommentiert hab. Es ist wirklich schwer da was drüber zufinden, da, trotz dem dass ich VB6.0 in die Suchmaschine eingebe, natürlich meistens auch VB.Net-Treffer angezeigt werden. Es geht um die veralteten Stringmethoden und -deklarationen. Z.B. das fixed String, das in Zeile 5 und 8 deklariert ist. Da hab ich Folgendes gefunden, aber da müsste ich den Visual Basic Namespace wieder aktivieren (und <VBFixedString(3)>Dim sID3 As String verwenden)und das bekomme ich nicht hin. Wenn ich im Projektmappen-Explorer auf My Project klicke öffnet sich nur das Fenster, das du im angehängten Screenshot siehst. Oder gibts da eine entsprechende Deklaration in VB.Net?
    Bilder
    • screenshot my project.jpg

      255,25 kB, 1.600×900, 32 mal angesehen