Versionsabgleich & Link zum Download in nur einer Textdatei?

  • VB.NET

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von Manawyrm.

    Versionsabgleich & Link zum Download in nur einer Textdatei?

    Hallo

    Wie bekommt man es hin, das in einer Textdatei mehrere Versionsnummern stehen und direkt dahinter der Link der aktualisierten Datei?

    So würde die Textdatei (die bereits vorhanden ist) zum Beispiel aussehen:

    Bereits vorhandene Versionsdatei:
    Programmdatei1=1.0.0.0_\update\programmdatei1
    Programmdatei2=1.0.3.2_\update\programmdatei2
    Programmdatei3=2.0.1.9_\update\programmdatei3
    Programmdatei4=1.0.0.0_\update\programmdatei4

    Wenn ich jetzt die Versionsnummer der aktuellen Dateien vom Server runterlade möchte ich das die Verionsdatei mit der vom Server runtergeladenen Versionsdatei verglichen wird und nur die Datei runtergeladen wird die auch wirklich eine neue Versionsnummer hat.

    Vom Server runtergeladene Versionsdatei:
    Programmdatei1=1.0.0.0_\update\programmdatei1
    Programmdatei2=8.2.1.1_\update\programmdatei2 (Diese hier runterladen)
    Programmdatei3=9.0.0.2_\update\programmdatei3 (... und diese hier, weil sie ebenfalls eine neue Version hat)
    Programmdatei4=1.0.0.0_\update\programmdatei4

    Mit einer Variable im Programm möchte ich dann den Link "\update\programmdatei1" vervollständigen.
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford
    Für diese Aufgabe solltest du dir ein Datenmodell erstellen. Eine Klasse mit "Programmname" (String), "Programmversion" (Version) und "Downloadadresse" (Uri) sollte diesen Zweck erfüllen.
    Dann downloadest du die Datei und liest sie zeilenweise ein. Jede Zeile Splittest du jeweils an "=" und "_" und packst die Ergebnisse in eine neue Instanz dieser Klasse. Die ganzen Instanzen kannst du in einer List(Of T) speichern.
    Das machst du dann genauso mit der lokalen Datei. Nun brauchst du nur noch die einzelnen Items der Beiden Listen miteinander vergleichen.
    Die Klassen habe ich erstellt, allerdings das danach verstehe ich nicht so ganz, kannst du mir Beispielweise ein kleines Codebeispiel machen?

    So wie ich es verstanden habe, soll was in der Textdatei steht (Beispiel):
    Programmdatei1=1.0.0.0_\update\programmdatei1
    Programmdatei2=1.0.3.2_\update\programmdatei2
    Programmdatei3=2.0.1.9_\update\programmdatei3
    Programmdatei4=1.0.0.0_\update\programmdatei4

    in die verschiedenen Klassen unterteilen?

    Programmdatei1 -> Programmname (bei mir Filename)
    1.0.0.0 -> Programmversion (bei mir Fileversion)
    \update\programmdatei1 -> Downloadadresse

    richtig?
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford
    Naja, ich denke mit:

    VB.NET-Quellcode

    1. Public Class Filename
    2. End Class


    VB.NET-Quellcode

    1. Public Class Fileversion
    2. End Class


    VB.NET-Quellcode

    1. Public Class Downloadaddress
    2. End Class
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford

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

    Das ist komplett falsch gedacht, tut mir leid. Du musst in Objekten denken, ein Eintrag ist ein Objekt, und ein Eintrag besitzt drei Eigenschaften, nämlich Programmname, Programmversion und Downloadlink. Das muss also alles in eine Klasse rein:

    VB.NET-Quellcode

    1. Public Class ProgramInfo
    2. Public Property Name As String
    3. Public Property Version As Version
    4. Public Property Link As Uri
    5. End Class
    Ah! Okay.

    @Artentus
    Das mit dem Splitten habe ich bislang noch nicht gemacht, brauche nicht auch dafür eine Textbox?

    VB.NET-Quellcode

    1. Dim Split() = Me.Label1.Text.Split(CChar("="))
    2. MsgBox(Split(1))
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford

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

    Nein, du lädst die den Dateiinhalt auf dem Server mit WebClient.DownloadString() in den Speicher (als String). Diesen String splittest du dann am Zeilenumbruch, damit du zunächst die einzelnen Zeilen vorliegen hast. Diese Zeilen kannst du dann mit einer For-Schleife durchlaufen und jeweils wieder an "=" und "_" splitten. Daraus erhältst du dann drei Teile, diese musst du richtig casten und dann einer neuen Instanz dieser Klasse zuweisen.
    Das wäre dann so? (Für erste Zeile erstmal)

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Label1.Click
    2. WebClient.DownloadString("http://.../Server.txt".Split("=", "_", " "))
    3. End Sub


    Fehler bei der Überladungsauflösung, da keine zugreifbare "Split" mit diesen Argumenten aufgerufen werden kann:
    "Public Function Split(separator() As String, count As Integer, options As System.StringSplitOptions) As String()": Der Wert vom Typ "String" kann nicht in "1-dimensionales Array von String" konvertiert werden.
    "Public Function Split(separator() As String, count As Integer, options As System.StringSplitOptions) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in Integer zu.
    "Public Function Split(separator() As String, count As Integer, options As System.StringSplitOptions) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in System.StringSplitOptions zu.
    "Public Function Split(separator() As Char, count As Integer, options As System.StringSplitOptions) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in 1-dimensionales Array von Char zu.
    "Public Function Split(separator() As Char, count As Integer, options As System.StringSplitOptions) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in Integer zu.
    "Public Function Split(separator() As Char, count As Integer, options As System.StringSplitOptions) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in System.StringSplitOptions zu.
    "Public Function Split(ParamArray separator() As Char) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in Char zu.
    "Public Function Split(ParamArray separator() As Char) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in Char zu.
    "Public Function Split(ParamArray separator() As Char) As String()": "Option Strict On" lässt keine impliziten Konvertierungen von String in Char zu.

    Oder geht das auch so?

    VB.NET-Quellcode

    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. WebClient.DownloadFileAsync(New Uri("http://.../SVersion.txt"), Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\SVersion.txt")
    3. End Sub


    VB.NET-Quellcode

    1. Private Sub WebClient_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles WebClient.DownloadFileCompleted
    2. Dim SVersion As String = IO.File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\SVersion.txt")
    3. End Sub
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford
    Das erste ging in die richtige Richtung. Der Fehler kommt erstmal, weil du eine Klammer falsch gesetzt hast (die ganz hinten muss vor das ".Split"). Außerdem musst die String, bei denen gesplittet werden soll, als Array angeben.
    Allerdings machst du da gerade zwei Schritte auf einmal, was aber nicht so ganz funktioniert. Du downloadest also erst die Datei und splittest sie am Zeilenumbruch

    VB.NET-Quellcode

    1. Dim lines = WebClient.DownloadString("http://.../Server.txt").Split({vbCrLf})
    und splittest dann jede dieser Zeilen nochmal.

    VB.NET-Quellcode

    1. For Each line In lines
    2. Dim parts = line.Split({"="c, "_"c})
    3. Next
    "parts" ist dann ein Array von Größe 3, bei dem im ersten Teil der Name, im zweiten die Version und im dritten der Link steht. Diese musst du nun noch richtig casten und dann einer neuen Instanz der obigen Klasse zuweisen.
    Danke, das wäre also schon mal dazu da, um alle Zeilen zu splitten bis es nicht mehr geht (?):

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim Lines = WebClient.DownloadString("http://.../Server.txt")
    3. For Each Line In Lines
    4. Dim Parts = Lines.Split({"="c, "_"c})
    5. Next
    6. End Sub


    Ich habe bei "Dim Parts = ..." Das "Line.Split" in "Lines.Split" geändert, weil ich nen Fehler bekomme: "Split" ist kein Member von "Char".

    Jetzt soll ich ja "casten" wie du geschrieben hast, aber bei MSDN verstehe ich mal wieder bei dem Beispiel nur Bahnhof.
    Ich nehme mal an, das du das hier gemeint hast? msdn.microsoft.com/de-de/library/vstudio/7k6y2h6x.aspx
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford
    Verändere nicht einfach Sachen am Code, den Fehler hättest du auch nicht bekommen, wenn du die erste Zeile richtig kopiert hättest.
    Und nein, in dem Fall ist mit Casten nicht DirectCast gemeint, auch wenn das das ist, was der Computer unter Casten versteht. Ich meine hier, dass du ja String zurückbekommst, du aber die Typen aus der klasse haben willst. Den namen brauchst du nicht zu casten, der ist ja ein String, aber aus den anderen beiden Teilen musst du einem eine Version und einmal eine Uri machen.
    Ich habe am Code was geändert, weil ich so ...

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim Lines = WebClient.DownloadString("http://.../Server.txt").Split({vbCrLf})
    3. For Each Line In Lines
    4. Dim Parts = Line.Split({"="c, "_"c})
    5. Next
    6. End Sub


    2 Fehler bekomme:

    1). Der Wert vom Typ "1-dimensionales Array von String" kann nicht in "Char" konvertiert werden.
    2). Der Ausdruck ist vom Typ "Object" und ist keine Auflistung.
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford
    Wie kann ich (z.B. mit einer MessageBox) kontrollieren ob er es mir richtig splittet?

    Könntest du mir vielleicht (vereinfacht) nochmal erklären, wie ich das jetzt alles in die Klasse "ProgramInfo" lade und vielleicht auch mit dem was ich im Visual Studio eventuell machen / hinzufügen muss? :)

    Ich bekomme das nicht so ganz hin ... :S
    Und eine Frage: Brauche ich nicht 2 Klassen? Einmal für die Programversion.txt und Server_version.txt?
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford

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

    Du kannst das Array wieder zusammenjoinen:

    VB.NET-Quellcode

    1. MessageBox.Show(String.Join(", ", lines))
    Die einzelnen Teile sind dann mit einem Komma getrennt.

    Edit: da du ja vorher sowieso keine Ruhe geben wirst:

    VB.NET-Quellcode

    1. Dim wc As New WebClient()
    2. Dim linesServer = wc.DownloadString("http://...").Split({vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
    3. Dim serverList As New List(Of ProgramInfo)
    4. For Each line In linesServer
    5. Dim parts = line.Split({"="c, "_"c})
    6. Dim info As New ProgramInfo()
    7. info.Name = parts(0)
    8. info.Version = Version.Parse(parts(1))
    9. info.Link = New Uri(Path.Combine("http://...", parts(2)))
    10. serverList.Add(info)
    11. Next
    12. Dim linesClient = File.ReadAllLines("C:\...")
    13. Dim clientList As New List(Of ProgramInfo)
    14. For Each line In linesClient
    15. Dim parts = line.Split({"="c, "_"c})
    16. Dim info As New ProgramInfo()
    17. info.Name = parts(0)
    18. info.Version = Version.Parse(parts(1))
    19. info.Link = New Uri(Path.Combine("http://...", parts(2)))
    20. clientList.Add(info)
    21. Next
    22. Dim result = From i1 In serverList Join i2 In clientList On i1.Name Equals i2.Name Where i1.Version > i2.Version Select i1
    result enthält dann alle Programme, für die eine neue Version vorliegt.

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

    Ein kompletter Code hätte es nicht sein müssen, aber danke :)
    Normalerweise möchte ich selber dahinter kommen wie das funktioniert, damit ich es später auch selber machen kann.

    Ich bekomme mit dem Code einen Fehler, aber ich habe keine Ahnung was man mir damit sagen will. (Was ist ein LINQ-Anbieter? ?()

    Ein Ausdruck vom Typ "System.Collections.Generic.List(Of Patcher.ProgramInfo)" kann nicht abgefragt werden. Stellen Sie sicher, dass kein Assemblyverweis und/oder Namespaceimport für den LINQ-Anbieter fehlt.
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford
    Ah!

    System.Linq war nicht importiert, jetzt scheint der Fehler weg zu sein.
    Nebenfrage: Könnte der Fehler auch auftreten wenn NET. Framework 2.0 genutzt wird? (Mein Projekt ist 4.0)
    "Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenig Leute damit beschäftigen." - Henry Ford