ich brauche mal etwas Rat. Ich komme nicht weiter (obwohl ich erfahren bin, wahrscheinlich irgendein dummer Fehler. ).
Situation: Ich habe eine Anwendung. Diese sucht zu Beginn nach neuen Updates, wenn eins oder mehr vorhanden ist, soll es das runterladen. Die Dateien heißen auf dem Server update_x.zip. Da eventuell in Update 10 eine wichtige neue Datei ist, die auch in Update 1337 gebraucht wird, muss natürlich jedes Update einzeln heruntergeladen werden.
Das ihr euch das vorstellen könnt. Allerdings habe ich das Problem, dass das Programm dann noch update 21 (das nicht vorhanden ist) herunterladen möchte, dann ein leeres Zip-Archiv entpacken will (0KB) und dann eine Fehlermeldung gibt (verständlich!).
Hat jemand einen Sourcecode dafür, oder könnte über meinen mal drüberschauen?
können, klar, wer soll dich davon abhalten.
ich persöhnlich würde es besser finden wenn du einfach den relevaten teil hier postet, dann besteht die möglichkeit das in zukunft jemand mit dem selben problem hier eine lösung findet.
Ich habe das in einer Console nochmal neu geschrieben, auch, damit man den Sourcecode noch überblicken kann (was bei der GUI nicht der Fall war!).
Das Problem nun:
in der version.cfg steht "420", also Client = 420. Serverversion sagt "423", also Server = 423.
Es funktioniert, allerdings bei 423 (also der Datei PATCH_423.zip) bricht er ab und sagt mir, es sei kein gültiges ZIP-Archiv, was ich auch glaube, da die Datei auf dem Server ~6 MB groß ist, bei mir jedoch nur ~ 122 KB. Hat der WebClient zu früh abgeschlossen?
Source:
€dit: Beim 2. Versuchen ist PATCH_423 ganze 0 KB groß. Wenn ich die Clientversion in der Datei auf 422 setze, lädt er einwandfrei herunter und es funktioniert, bei 421 auch, aber weshalb bei 420 nicht?
€dit²: Scheinbar lädt er bei mehr als zwei Updates, die ausstehen, das dritte nicht komplett runter, mal ist "423" 100 KB, mal 0 oder 577 KB groß.
Ich habe das in einer Console nochmal neu geschrieben, auch, damit man den Sourcecode noch überblicken kann (was bei der GUI nicht der Fall war!).
Das Problem nun:
in der version.cfg steht "420", also Client = 420. Serverversion sagt "423", also Server = 423.
Es funktioniert, allerdings bei 423 (also der Datei PATCH_423.zip) bricht er ab und sagt mir, es sei kein gültiges ZIP-Archiv, was ich auch glaube, da die Datei auf dem Server ~6 MB groß ist, bei mir jedoch nur ~ 122 KB. Hat der WebClient zu früh abgeschlossen?
Source:
€dit: Beim 2. Versuchen ist PATCH_423 ganze 0 KB groß. Wenn ich die Clientversion in der Datei auf 422 setze, lädt er einwandfrei herunter und es funktioniert, bei 421 auch, aber weshalb bei 420 nicht?
€dit²: Scheinbar lädt er bei mehr als zwei Updates, die ausstehen, das dritte nicht komplett runter, mal ist "423" 100 KB, mal 0 oder 577 KB groß.
Hast du eine Idee, tolio?
Servus,
ich habe deinen SourceCode ausprobiert und es kam kein Fehler, alles hat funktioniert. Selbst der Patch_423.zip wurde geladen und entpackt. Gtestet habe ich es über meinen FTP-Server.
Spontan würde mir einfallen:
- try/catch ggf. wird eine Fehlermeldung geschmissen.
- Überprüfen, ob die Dateinamen richtig sind, ggf. Leerzeichen dazwischen.
- Debuggen. Einfach alle Schritte durchgehen und überprüfen, ob die Werte richtig gesetzt werden.
- ggf. die richtige URL's geben, damit man selber ausprobieren/debuggen kann
Ich würde gerne Verbesserungsvorschläge geben.
- Verwende try/catch
- Verwende bei IDisposable Objekten
(z.B. WebClient, StreamReader/Writer usw)
- Vermeide
Code:
Convert.ToInt32();
und nimm besser
Code:
bool = int.TryParse();
Dies hat zum Vorteil, dass die Exception bereits von der Funktion selbst ausgwertet wird. ( )
- Nach jedem Patch rufst Du die Funktion
Code:
getServerVersion();
erneut auf. Ich bin der Meinung, dass es reichen würde, wenn Du die ServerVersion einmalig am Programmstart abfragst.
Ich habe mir mal die Mühe gemacht einen Updater zu schreiben, der genau diese Aufgabe wie deiner absolvieren soll. Man brauch mindestens das .Net Framework 4.5, ich mit der TPL gearbeitet habe. Was noch nicht vorhanden ist, ist das setzten der aktuellen Version für den Client.
Code:
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Ionic.Zip;
namespace Updater
{
class Program
{
static string _ServerUrl = @"http://url./Updater/Version.txt";
static string _PatchUrl = @"http://url.de/Updater/Patch_";
static string _LocalFolder = Environment.CurrentDirectory;
static string _ClientUrl = string.Format(@"{0}\Version.txt", _LocalFolder);
static void Main(string[] args)
{
Task.Run(() => MainAsync(args)).Wait();
Console.ReadKey();
}
static async Task MainAsync(string[] args)
{
int serverVersion, clientVersion;
string server, client;
try
{
server = await ServerVersion(_ServerUrl);
client = await ClientVersion(_ClientUrl);
Console.WriteLine("Server: {0}", server);
Console.WriteLine("Client: {0}", client);
int.TryParse(server, out serverVersion);
int.TryParse(client, out clientVersion);
if (clientVersion < serverVersion)
{
Console.WriteLine("Update vorhanden!");
while (clientVersion < serverVersion)
{
clientVersion++;
Console.WriteLine("Downloading Patch: {0}", clientVersion);
if (!await GetFilesFromServer(clientVersion.ToString()))
{
Console.WriteLine("Patch Nummer {0} konnte nicht geladen werden.", clientVersion);
}
}
}
else
{
Console.WriteLine("Kein Update vorhanden.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static async Task<string> ServerVersion(string Url)
{
if (string.IsNullOrEmpty(Url))
throw new ArgumentNullException("Url", "Url darf nicht NULL oder leer sein.");
string ret = string.Empty;
using (WebClient wc = new WebClient())
{
//wc.UseDefaultCredentials = true;
//wc.Credentials = new NetworkCredential("", "");
ret = await wc.DownloadStringTaskAsync(Url);
}
return ret;
}
static async Task<string> ClientVersion(string FilePath)
{
if (string.IsNullOrEmpty(FilePath))
throw new ArgumentNullException("FilePath", "FilePath darf nicht NULL oder leer sein.");
string ret = string.Empty;
using (StreamReader sr = new StreamReader(FilePath))
{
ret = await sr.ReadToEndAsync();
}
return ret;
}
static async Task<bool> GetFilesFromServer(string PatchVersion)
{
if (string.IsNullOrEmpty(PatchVersion))
throw new ArgumentNullException("PatchVersion", "Die Patchversion darf nicht NULL oder leer sein.");
bool success = false;
string patchUrl = string.Format(@"{0}{1}.zip", _PatchUrl, PatchVersion);
string localFile = string.Format(@"{0}\Patch_{1}.zip", _LocalFolder, PatchVersion);
using (WebClient wc = new WebClient())
{
wc.DownloadProgressChanged += (s, e) =>
{
//Console.WriteLine(e.ProgressPercentage);
};
wc.DownloadFileCompleted += (sender, args) =>
{
Console.WriteLine("Patch erfolgreich geladen.");
Unzip(localFile);
};
//wc.UseDefaultCredentials = true;
//wc.Credentials = new NetworkCredential("", "");
await wc.DownloadFileTaskAsync(new Uri(patchUrl), localFile);
success = true;
}
return success;
}
static void Unzip(string Filepath)
{
if (string.IsNullOrEmpty(Filepath))
throw new ArgumentNullException("Filepath", "Filepath darf nicht NULL oder leer sein.");
string destination = @"";
try
{
using (ZipFile zip = ZipFile.Read(Filepath))
{
Console.WriteLine("Datei wird entpackt.");
foreach (ZipEntry entry in zip)
{
entry.Extract(destination, ExtractExistingFileAction.OverwriteSilently);
Console.WriteLine("Patching: {0}", entry.FileName);
}
}
File.Delete(Filepath);
Console.WriteLine("{0} wurde gelöscht.", Filepath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Hallo! Danke, für deinen Code. Ich habe es bereits debuggt und natürlich wurde auch ein Fehler geworfen, nämlich, dass 423 kein gültiges ZIP-Archiv ist. Ich teste deinen Code mal.
€dit: Zu welchem Namespace gehört dieses Objekt?
€dit²: Habe nun statt dem Objekt lediglich "true" gesetzt, funktioniert auch. Wäre es sinnvoll, wenn alle Updates installiert sind, einfach die Clientversion auf die Serverversion zu setzen?
Hallo! Danke, für deinen Code. Ich habe es bereits debuggt und natürlich wurde auch ein Fehler geworfen, nämlich, dass 423 kein gültiges ZIP-Archiv ist. Ich teste deinen Code mal.
€dit: Zu welchem Namespace gehört dieses Objekt?
€dit²: Habe nun statt dem Objekt lediglich "true" gesetzt, funktioniert auch. Wäre es sinnvoll, wenn alle Updates installiert sind, einfach die Clientversion auf die Serverversion zu setzen?
Du benutzt doch die oder?
Die Methode ZipEntry.Extract() erwartet ein Dateipfad und/oder eine das enum ExtractExistingFileAction, welches besagt was passieren soll, falls eine Datei vorhanden ist.
Dann hättest Du das Problem, falls ein Update nicht erfolgreich ist, wird die Serverversion gesetzt.
Du benutzt doch die oder?
Die Methode ZipEntry.Extract() erwartet ein Dateipfad und/oder eine das enum ExtractExistingFileAction, welches besagt was passieren soll, falls eine Datei vorhanden ist.
Dann hättest Du das Problem, falls ein Update nicht erfolgreich ist, wird die Serverversion gesetzt.
Ich würde es so ähnlich machen, wie in meinem Code, nur vorher überprüfen, ob dass entpacken erfolgreich war.
Hier mal meinen Vorschlag als Pseudocode:
Ich persönlich, würde das mit den Archiven wie folgt handhaben: Erstelle jeweils bei einem Patch, oÄ. einfach das Archiv neu und stelle nur das bereit. Wenn ein Client nun eine Verbindung zum Server herstellt, siehst Du nach, welche Version er hat und stellst dann entsprechend das Archiv bereit. Anders herum wäre dann das Archiv unnötig groß und er würde willkürlich alle Dateien herunterladen.
Und je nach Version kannst Du ja festlegen, welche Dateien benötigt werden bzw. bereits wurden und darauf agieren.
[Update] 8 Ball Pool Line Length and Size Cheat Update 2013 Video 02/05/2013 - Facebook - 7 Replies Hi 8 Ball Pool players..
In this video,I'll show how to make line length and size cheat (it's updated)
(you can visit Hasan Özükcan - YouTube for more cheats video)
8 Ball Pool Line Length and Size Cheat Update 2013 - YouTube
-open 8 ball pool with mozilla