C# Download Manager Projekt

PeterParty

Lt. Junior Grade
Registriert
Aug. 2008
Beiträge
282
Nabend,

Ich bin derzeit bei einem kleinen Projekt für eine Virtuelle Airline ein Download/Installer Manager zu erstellen.

Dieser Sollte die Bemalungen (Paints für das Flugzeug) runterladen und installieren können.

Vlt. erstmal ein Pic:



Die .exe Dateien der bemaulungen liegen alle auf dem Webspace der VA genauso wie eine News.txt und Livery.txt.

Nun das Problem:

Ich möchte wenn ich in der checkedListBox was auswähle und auf download klicke das er sie alle nacheinander runterlädt, bis jetzt habe ich es nur geschaft das er sie einzelnd runterlädt und nur wenn sie Markirt sind? Hier mal der Code vom Download Button:

Code:
        private void button1_Click(object sender, EventArgs e)
        {
            liveries foobar = checkedListBox1.SelectedItem as liveries;

            if (label1.Text == "Die Verbindung zum Server wurde hergestellt")
            {
                string link = foobar.m_link;
                string name = @"downloads\" + foobar.m_liveryname + ".exe";
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                webClient.DownloadFileAsync(new Uri(link),name);
            }

            else
            {
                MessageBox.Show("Die Verbindung zum Server konnte nicht hergestellt werden! Bitte Prüfen sie ihre Internetverbindung");
            }
        }

Code von der liveries klasse:

Code:
class liveries
    {
        public string m_liveryname;
        public string m_link;


        public liveries()
        { }
        public override string ToString()
        {
            return this.m_liveryname;
        }

        public void Load(string reader)
        {
            string[] werte = reader.Split('|');
            m_liveryname = werte[0];
            m_link = werte[1];
        }

        public string EMaiL
        {
            get { return m_link; }
        }
    }

Code vom einlesen der Liveries aus der Aktuellen Liveries.txt:

Code:
checkedListBox1.Items.Clear();
                    List<liveries> list = new List<liveries>();
                    StreamReader reader = new StreamReader(@"source\liveries.txt");

                    while (reader.EndOfStream == false)
                    {
                        liveries fooBar = new liveries();
                        fooBar.Load(reader.ReadLine());
                        list.Add(fooBar);

                    }
                    reader.Close();
                    checkedListBox1.Items.AddRange(list.ToArray());

Er lädt die Aktuelle liveries.txt bei jedem Programm Start vom Server runter, sie schaut so aus:

name|link
name|link
name|link
name|link
etc.....

Ich denke das Problem ist das ich nur mit "checkedListBox1.SelectedItem" arbeiten kann und nicht mit chekedItem oder so...

Ich hoffe jemand kann mir helfen und wenn ihr noch Informationen benötigt fragt mich einfach.

Mit freundlichen Grüßen
Peter
 
Was willst du genau? Nur die angehakten Einträge runterladen?
Das muss mit checkedListBox1.CheckedItems gehen! Dann erhälst du alle mit einem Haken versehene Einträge. Dann einfach mit foreach (liveries l in checkedListBox1.CheckedItems) { /* Datei runterladen */ } durch die Liste gehen und die Datei runterladen. Ein gleichzeitiger Download aller ausgewählten Dateien geht nicht so einfach...
 
leimer schrieb:
Was willst du genau? Nur die angehakten Einträge runterladen?

Genau man soll von oben bis unten alle anhaken und auf Downlaod klicken er soll sie dan nacheinander runterladen....
 
Hi,

Das Runterladen der Datei funktioniert schon pefekt er liest sie auch etc....

Hier mal der Code:

Code:
                    foreach (liveries liver in checkedListBox1.CheckedItems)
                    {
                        string link = liver.m_link;
                        string name = @"downloads\" + liver.m_liveryname + ".exe";
                        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                        webClient.DownloadFile(new Uri(link), name);
                        progressBar1.Minimum = 0;
                    }


Mit DownloadFileAsync bekomme ich ein Fehler das es nicht gleichzeitig funktioniert, mit DownloadFile lädt er die dateien nacheinader runter aber er zeigt nichts mehr in meiner progressbar an? weiß einer woran das noch liegen kann?
 
DownloadProgressChanged wird nur bei asynchronen Downloads geworfen. ProgressChanged wird also in deinem Fall nie aufgerufen.
 
Naja du könntest einfach nach jedem abgeschlossenen Download manuell den Fortschritt setzten. Halt dann immer nach Anzahl der geladenen Files/Anzahl aller Files.

Eine andere Möglichkeit wäre noch das ganz Asynchron zu machen. Weil ich gute Laune hab, hab ich das ganze mal prinzipiell aufgeschrieben so wies mir grad eingefallen ist (hab den code nicht compiliert, übernehme also keine garantie, sollte aber funktionieren):
Code:
        private Queue<liveries> filesToDownload = new Queue<liveries>();

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            foreach (liveries liver in checkedListBox1.CheckedItems)
            {
                filesToDownload.Enqueue(liver); // Fügt Objekt in die Queue ein
            }

            DownloadNextFileFromQueue();
        }


        private void DownloadNextFileFromQueue()
        {
            if (filesToDownload.Any())
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted);

                var liver = filesToDownload.Dequeue(); // Liest objekt aus der queue aus und löscht es
                string link = liver.m_link;
                string name = @"downloads\" + liver.m_liveryname + ".exe";

                webClient.DownloadFileAsync(new Uri(link), name);
            }
            else
            {
                   // Alle Dateien aus der queue wurden geladen
            }
        }

        void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            DownloadNextFileFromQueue();

            // update status oder so?!
        }

Die Idee ist einfach eine Liste von files zu erstellen, dann das erste File zu laden und aus der Liste zu löschen. Ist der Download abgeschlossen wird, falls noch andere Files in der Liste sind, das nächste geladen.

Hier könntest du auch noch DownloadProgressChanged verwenden, kann würde die progressbar halt für jedes file immer von 0 - 100 gehen.
Außer du verrechnest das dann vllt. noch mit der gesamten anzahl der zu ladenden files und der anzahl der schon geladenen.
Generell würd ich dir wirklich empfehlen das ganze versuchen asynchron zu machen.
 
Zuletzt bearbeitet:
Vielen Dank!
Code:
void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
DownloadNextFileFromQueue();
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
}

Wenn ich hier den DownloadProgressChanged verwende passiert leider nichts ;( vlt. stehe ich auch grade was aufm Schlauch...... :)

MfG
Peter

EDIT: Grade gesehen, bei der ersten datei wird die progressbar nicht benutzt bei der zweiten Datei funktioniert sie perfekt und bei der Dritten Datei kommt eine Fehlermeldung.
 
Zuletzt bearbeitet:
Einfach da abonnieren wo du auach das Completed event abonniert hast
Code:
WebClient webClient = new WebClient();                
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

Sonst abonnierst du das event ja erst nachdem du die erste datei geladen hast.
 
Hi,

hatte ich schon gemacht bloß bekomme ich leider immernoch die NotSupportedException:
WebClient unterstützt keine gleichzeitigen E/A-Vorgänge.

Ich denke es liegt immernoch am Async?

Ist es vlt. möglich ein Timmer einzubauen so dass er nach jedem Download 2 Sekunden oder so wartet?

Danke für deine Hilfe
 
Kein Ding :)

Also eigentlich sollte der Webclient nicht mehrere Downloads gleichzeitig machen, da beim Completed Event auch wirklich alles abgeschlossen ist. Ein Timer ist da eher ne instabile bzw. garkeine Lösung.
Hast du auch so wie ich im Code bei jedem Schleifendurchgang nen neuen WebClient erstellt?

Was mir da nämlich grad in den Sinn gekommen ist: wenn du ihn nicht neu erstellt hast, hast du dem WebClient nach dem zweiten Durchgang schon zweimal die EventHandler zugewiesen.
(2x webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted))
Er ruft also den Completed handler zwei mal auf, der versucht zwei Downloadvorgänge zu starten => Fehler.

Was du versuchen kannst: Wie ich bei jedem Vorgang den WebClient neu erstellen,
oder einmal, z.B. beim Button.Click event, den Client erstellen, die Handler zuweisen und nicht bei jedem Durchgang wieder zuweisen.

Also einfach einmal:
Code:
private void button1_Click(object sender, RoutedEventArgs e)        {

webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

....
}
 
Zuletzt bearbeitet:
Es scheint es lag am WebClient ich hatte einen für das komplette projekt .....

habe das mal geändert und es scheint alles zu funktionieren ;)

Ich danke dir, jetzt mache ich mal weiter mit dem rest was ich noch vorhabe.
Schönen Abend noch
 
Der Download funktioniert jetzt komplett alle .exe Dateien werden in dem Ordner Downloads gespeichert.

Jetzt möchte ich das ich die Dateien auch Installieren kann.

Code:
            string pfad = @"downloads\";
            checkedListBox2.Items.Clear();
            System.IO.FileInfo[] fi = new System.IO.DirectoryInfo(pfad).GetFiles();
            foreach (var fileInfo in fi)
            {
                checkedListBox2.Items.Add(fileInfo.Name);
            }

Er liest alle dateien aus dem Ordner uas und listet sie in der checkbox wie kann ich sie jetzt installieren?


MfG
Peter
 
Zurück
Oben