Exe soll nach Download starten (async/await-Problem)

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von korni.

    Exe soll nach Download starten (async/await-Problem)

    Guten Morgen,

    achtung, es kommt ein längerer Text, ich hab versucht es auf das Wesentliche zu kürzen. Hauptproblem: ich steige durch die async/await Thematik schwer
    durch und zerbreche mir seit zwei Tagen den Kopf. Vielleicht hat jemand 'nen Gedanken, den er teilen kann.

    Ich möchte eine exe aus dem Internet downloaden und diese anschließend öffnen. Dies geschieht über einen Download-Button, der gleichzeitig
    eine Progressbar füllt. Die einzelnen Codekomponenten funktionieren soweit. Nun möchte ich einen Download-Butten drücken, der den Download
    startet und die Progressbar durchläuft und DANACH die exe startet.

    VB.NET-Quellcode

    1. Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnDownload.Click
    2. Dim urlzeile As String = "https://download.etcetc.x86_DEU.exe"
    3. 'Maximum der Progressbar setzen
    4. ProgressBar1.Maximum = GetFileSize(urlzeile)
    5. 'ProgressBar Fortschritt auf 0 setzen
    6. ProgressBar1.Value = 0
    7. Timer1.Enabled = True
    8. Task.Factory.StartNew(Function() DownloadFile())
    9. ' !!! Hier ist mein Problem. Code läuft ins try rein, bevor download fertig ist (logisch, is ja auch async, wa?) wie kann ich abfragen ob download durch is?
    10. Try
    11. Process.Start("C:\SQLExe-Test\sqltest.exe")
    12. lblStatusExe.Text = "2. Exe wird ausgeführt."
    13. lblStatusDownload.ForeColor = Color.Green
    14. Catch ex As Exception
    15. MessageBox.Show(ex.Message, "Exe wird nicht ausgeführt.")
    16. lblStatusExe.Text = "2. Exe wird nicht ausgeführt."
    17. lblStatusExe.ForeColor = Color.Red
    18. End Try
    19. End Sub


    Mein Problem ist nun, das der Download asynchron im Hintergrund läuft und der Code schon weiterläuft zur exe, die natürlich noch nicht fertig
    runtergeladen ist und die Fehlermeldung kommt, das die Exe noch nicht fertig ist.

    Ich muss/möchte abfragen, "ist download fertig? - dann starte exe". Hab das mit if-abfrage versucht aber der hüpft sofort in die Abfrage und sagt wieder "Nö Download noch nicht fertig".

    Zum Verständnis noch den Rest des Codes und die Funktionen:

    VB.NET-Quellcode

    1. ''' Hier die Funktion für den asynchronen Download
    2. Private Function DownloadFile() As Boolean
    3. Dim webClient1 As New WebClient()
    4. webClient1.DownloadFileAsync(New Uri("https://download.etcetc.x86_DEU.exe"), "C:\SQLExe-Test\sqltest.exe")
    5. Return True
    6. End Function
    7. ''' Die Funktion gibt die Größe der zu downloadenden Datei zurück für die Progressbar
    8. Public Function GetFileSize(url As String) As Long
    9. Using obj As New WebClient()
    10. Using s As Stream = obj.OpenRead(url)
    11. Return Long.Parse(obj.ResponseHeaders("Content-Length").ToString())
    12. End Using
    13. End Using
    14. End Function
    15. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    16. 'Der Timer fragt die aktuelle Größe der Datei ab und setzt den Progressbar-Fortschritt
    17. Dim zielzeile As String = "C:\SQLExe-Test\sqltest.exe"
    18. Dim info As New FileInfo(zielzeile)
    19. ProgressBar1.Value = info.Length
    20. LabStreamLength.Text = info.Length
    21. Application.DoEvents()
    22. End Sub



    Danke an alle die bis hierher gelesen haben ^^
    TaskFactory? DownloadFileAsync? DoEvents? Uh oh. Schau ggf. nochmal hier nach. Async, Await und Task

    VB.NET-Quellcode

    1. Private Async Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnDownload.Click
    2. Dim urlzeile As String = "https://download.etcetc.x86_DEU.exe"
    3. 'Maximum der Progressbar setzen
    4. ProgressBar1.Maximum = GetFileSize(urlzeile)
    5. 'ProgressBar Fortschritt auf 0 setzen
    6. ProgressBar1.Value = 0
    7. Timer1.Enabled = True
    8. Dim webClient1 As New WebClient()
    9. Await Threading.Tasks.Task.Run(Sub() webClient1.DownloadFile(New Uri("https://download.etcetc.x86_DEU.exe"), "C:\SQLExe-Test\sqltest.exe"))
    10. Process.Start("C:\SQLExe-Test\sqltest.exe")
    11. lblStatusExe.Text = "2. Exe wird ausgeführt."
    12. lblStatusDownload.ForeColor = Color.Green
    13. End Sub

    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.
    In welcher Zeile konkret? Das Async-Await-Konstrukt besteht aus den Teilen Async (bei mit Zeile#1: Private Async Sub) und Await (Z#12: Await Threading.Tasks...).
    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.
    @hjerteblod Ich kann in deinem Code keine Methode finden die als "async" gekennzeichnet ist und dementsprechend auch kein "await". Das Einzigste was ich sehe ist das du einen neuen Task startest und nie auf diesen wartest (Stichwort "await").
    @VaporiZed ja du hast recht, fuck ich schau seit drei tagen auf den code und hab das jetzt im testprogramm aber nicht hier reinkopiert, tut mir leid. im kopf
    hatte ich den plan das einzubauen, weil ich denke das das die lösung ist aber oben im code ist es nicht.

    VB.NET-Quellcode

    1. Private Async Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnDownload.Click
    2. Dim urlzeile As String = "https://download.etcetc.x86_DEU.exe"
    3. 'Maximum der Progressbar setzen
    4. ProgressBar1.Maximum = GetFileSize(urlzeile)
    5. 'ProgressBar Fortschritt auf 0 setzen
    6. ProgressBar1.Value = 0
    7. Timer1.Enabled = True
    8. Await Task.Factory.StartNew(Function() DownloadFile())
    9. Try
    10. Process.Start("C:\SQLExe-Test\sqltest.exe")
    11. lblStatusExe.Text = "2. Exe wird ausgeführt."
    12. lblStatusDownload.ForeColor = Color.Green
    13. Catch ex As Exception
    14. MessageBox.Show(ex.Message, "Exe wird nicht ausgeführt.")
    15. lblStatusExe.Text = "2. Exe wird nicht ausgeführt."
    16. lblStatusExe.ForeColor = Color.Red
    17. End Try
    18. End Sub


    ich hab hier 5 seiten zu der thematik auf und es macht nicht klick, deswegen wollte ich es ins forum werfen für feedback. where is the wochenende when needed

    @korni ja du hast recht, ich habs verballert
    @hjerteblod: Öhm, Post#2 ist getestet und läuft. Das ist Dir bewusst?
    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.
    @korni es funktioniert leider noch nicht.
    dort wird der download gestartet und gespeichert. das wird async gemacht, das heißt im hintergrund und ohne bildschirm einzufrieren. oder?
    und dann soll der "exe starten" code warten und wenn der download durch ist, soll er starten. but how? :D ich muss (und hätte eher) schon sagen
    sollen, das ein kollege mir den code so ein bisschen übergeholfen hat und ich soll jetzt "nur noch" einbauen das die exe startet. ich versteh seinen
    code soweit aber hab vorher nie was mit async gemacht und kann ihn gerade nicht fragen.
    @hjerteblod Wie sieht den aktuell der Code aus? Hast du den Code aus Post #2 übernommen?

    Wenn du noch den alten Code hast musst du das webClient1.DownloadFileAsync in ein webClient1.DownloadFile ändern.

    Ansonsten gibt deine Methode Private Function DownloadFile() As Boolean direkt true zurück.
    Hintergrund ist das er ja das File Async herunterladet und somit der Hauptthread weiterlaufen kann. Wenn du dann keine Await einbaust geht er direkt in das "return true" weiter.

    Wobei dein Aufbau momentan etwas unlogisch ist. Die Lösung in Post #2 sieht da schon schöner aus.

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

    @korni @VaporiZed ich danke euch bis hierher schon mal sehr für die schnelle hilfe. es läuft noch nicht ganz aber ich überarbeite den code gerade mit euren anmerkungen und geb dann nochmal feedback

    @korni meinst du, ich muss das await in die private function download file einbauen damit der nicht sofort ins true reinlädt? hab ich mich nämlich auch gefragt ob das await einfach an der falschen stelle ist.

    aktueller code:

    VB.NET-Quellcode

    1. ''' Hier die Funktion für den asynchronen Download
    2. Private Function DownloadFile() As Boolean
    3. Dim webClient1 As New WebClient()
    4. webClient1.DownloadFile(New Uri("https://download.blablaexe"), "C:\SQLExe-Test\sqltest.exe")
    5. Return True
    6. End Function
    7. ''' Die Funktion gibt die Größe der zu downloadenden Datei zurück für die Progressbar
    8. Public Function GetFileSize(url As String) As Long
    9. Using obj As New WebClient()
    10. Using s As Stream = obj.OpenRead(url)
    11. Return Long.Parse(obj.ResponseHeaders("Content-Length").ToString())
    12. End Using
    13. End Using
    14. End Function
    15. Private Async Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnDownload.Click
    16. Dim urlzeile As String = "https://download.blablaexe"
    17. 'Maximum der Progressbar setzen
    18. ProgressBar1.Maximum = GetFileSize(urlzeile)
    19. 'ProgressBar Fortschritt auf 0 setzen
    20. ProgressBar1.Value = 0
    21. Timer1.Enabled = True
    22. Dim webClient1 As New WebClient()
    23. Await Threading.Tasks.Task.Run(Sub() webClient1.DownloadFile(New Uri("https://download.etcetc.x86_DEU.exe"), "C:\SQLExe-Test\sqltest.exe"))
    24. Try
    25. Process.Start("C:\SQLExe-Test\sqltest.exe")
    26. lblStatusExe.Text = "2. Exe wird ausgeführt."
    27. lblStatusDownload.ForeColor = Color.Green
    28. Catch ex As Exception
    29. MessageBox.Show(ex.Message, "Exe wird nicht ausgeführt.")
    30. lblStatusExe.Text = "2. Exe wird nicht ausgeführt."
    31. lblStatusExe.ForeColor = Color.Red
    32. End Try
    33. End Sub
    34. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    35. 'Der Timer fragt die aktuelle Größe der Datei ab und setzt den Progressbar-Fortschritt
    36. Dim zielzeile As String = "C:\SQLExe-Test\sqladv.exe"
    37. Dim info As New FileInfo(zielzeile)
    38. ProgressBar1.Value = info.Length
    39. LabStreamLength.Text = info.Length
    40. Application.DoEvents()
    41. End Sub
    42. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    43. Dim urlzeile As String = "https://download.blablaexe"
    44. If DownloadFile() = True Then
    45. Try
    46. Process.Start("C:\SQLExe-Test\sqltest.exe")
    47. lblStatusExe.Text = "2. Exe wird ausgeführt."
    48. lblStatusDownload.ForeColor = Color.Green
    49. Catch ex As Exception
    50. ' MessageBox.Show(ex.Message, "Exe wird nicht ausgeführt.")
    51. lblStatusExe.Text = "2. Exe wird nicht ausgeführt."
    52. lblStatusExe.ForeColor = Color.Red
    53. End Try
    54. End If
    55. End Sub

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

    Die WebClient-Klasse hat ein Event DownloadFileCompleted, welches ausgelöst wird, wenn eben der Download fertig ist.

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.ComponentModel
    3. Public Class Form1
    4. Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim url = "http://speedtest.tele2.net/10MB.zip
    6. "
    7. Using wC As New WebClient With {.Proxy = Nothing}
    8. AddHandler wC.DownloadProgressChanged, AddressOf DownloadProgessChanged
    9. AddHandler wC.DownloadFileCompleted, AddressOf DownloadCompleted
    10. Await wC.DownloadFileTaskAsync(url, "e:\testData.zip")
    11. End Using
    12. End Sub
    13. Private Sub DownloadProgessChanged(sender As Object, e As DownloadProgressChangedEventArgs)
    14. ProgressBar1.Value = e.ProgressPercentage
    15. End Sub
    16. Private Sub DownloadCompleted(sender As Object, e As AsyncCompletedEventArgs)
    17. If e.Error Is Nothing Then
    18. Me.Text = "Download done."
    19. Process.Start("e:\testData.zip")
    20. Else
    21. Me.Text = "Download failed."
    22. End If
    23. End Sub
    24. End Class
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @SpaceyX der code sieht super aus, vielen dank.
    allerdings bekomme ich immer diese meldung: System.Net.WebException

    Innere Ausnahme 1:
    UnauthorizedAccessException: Der Zugriff auf den Pfad "C:\Users\AS\Desktop\testdata.zip" wurde verweigert.

    ich habs mit adminrechten versucht und an verschiedenen Stellen aber immer wieder kommt das.
    Dass Du da Deine Dateiangaben in Z#7, #12 und #23 setzen musst, ist Dir aber schon klar.
    @hjerteblod:
    Ggf. den EventHandler noch etwas abändern:

    VB.NET-Quellcode

    1. Private Async Sub DownloadCompleted(sender As Object, e As AsyncCompletedEventArgs)
    2. If e.Error Is Nothing Then
    3. Me.Text = "Download done."
    4. Await Threading.Tasks.Task.Delay(1000)
    5. Process.Start("e:\testData.zip")
    6. Else
    7. Me.Text = "Download failed."
    8. End If
    9. End Sub

    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.
    ach was ;) ja das habe ich geändert.
    @korni @VaporiZed
    habs gelöst. im timer wird abgefragt, wann progressbar maximum ist und dann wird die exe geöffnen. getestet und funktioniert. manchmal hat man echt ein brett vor dem kopf. danke
    an alle die geholfen haben.

    VB.NET-Quellcode

    1. ''' Hier die Funktion für den asynchronen Download
    2. Private Function DownloadFile() As Boolean
    3. Dim webClient1 As New WebClient()
    4. webClient1.DownloadFileAsync(New Uri("https://download.exe"), "C:\SQLExe-Test\sqltest.exe")
    5. Return True
    6. End Function
    7. ''' Die Funktion gibt die Größe der zu downloadenden Datei zurück für die Progressbar
    8. Public Function GetFileSize(url As String) As Long
    9. Using obj As New WebClient()
    10. Using s As Stream = obj.OpenRead(url)
    11. Return Long.Parse(obj.ResponseHeaders("Content-Length").ToString())
    12. End Using
    13. End Using
    14. End Function
    15. Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnDownload.Click
    16. Dim urlzeile As String = "https://download.exe"
    17. 'Maximum der Progressbar setzen
    18. ProgressBar1.Maximum = GetFileSize(urlzeile)
    19. 'ProgressBar Fortschritt auf 0 setzen
    20. ProgressBar1.Value = 0
    21. Timer1.Enabled = True
    22. Dim webClient1 As New WebClient()
    23. Task.Factory.StartNew(Function() DownloadFile())
    24. End Sub
    25. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    26. 'Der Timer fragt die aktuelle Größe der Datei ab und setzt den Progressbar-Fortschritt
    27. Dim zielzeile As String = "C:\SQLExe-Test\sqltest.exe"
    28. Dim info As New FileInfo(zielzeile)
    29. ProgressBar1.Value = info.Length
    30. LabStreamLength.Text = info.Length
    31. Application.DoEvents()
    32. If ProgressBar1.Value = ProgressBar1.Maximum Then
    33. Timer1.Enabled = False
    34. Try
    35. Process.Start("C:\SQLExe-Test\sqltest.exe")
    36. lblStatusExe.Text = "2. Exe wird ausgeführt."
    37. lblStatusDownload.ForeColor = Color.Green
    38. Catch ex As Exception
    39. MessageBox.Show(ex.Message, "Exe wird nicht ausgeführt.")
    40. lblStatusExe.Text = "2. Exe wird nicht ausgeführt."
    41. lblStatusExe.ForeColor = Color.Red
    42. End Try
    43. End If
    44. End Sub

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

    Mhh, der Desktop-Folder sollte eigentlich keine Admin-Rechte erfordern. Schau mal, ob der evtl. schreibgeschützt ist... Ansonsten probier mal das....


    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o