Autor Beitrag
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.06.11 10:46 
Ich mache einen FTP-Download mit DownloadDataAsync:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
void Start () {      
    ftpRequest = new WebClient();
    Debug.Log("Start: " + sourceFilePath + "/" + filename);
    System.Uri uri = new System.Uri(sourceFilePath + "/" + filename);
    try {
      ftpRequest.Credentials = new NetworkCredential(user, password);
      ftpRequest.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
      ftpRequest.DownloadDataCompleted += new DownloadDataCompletedEventHandler(DownloadCompleteCallback);
      ftpRequest.DownloadDataAsync(uri);      
    }
    catch(System.Exception e) {
      Debug.Log("Start: " + e.Message);
    }
  }
  
  void DownloadProgressCallback(System.Object sender, DownloadProgressChangedEventArgs e) {    
    bytesReceived += e.BytesReceived;    
    progressOutput = String.Format("{0:N} Bytes von {1:N} Bytes empfangen ({2:D}%)", bytesReceived, e.TotalBytesToReceive, e.ProgressPercentage);
    Debug.Log(progressOutput);
  }
  
  void DownloadCompleteCallback(System.Object sender, DownloadDataCompletedEventArgs e) {    
    try {
      byte[] data = (byte[])e.Result;
      if (data != null) {
        Debug.Log("DownloadCompleteCallback: " + destFilePath + "\\" + filename);
        FileStream fs = new FileStream(destFilePath + "\\" + filename, FileMode.Create);      
        fs.Write(data, 0, data.Length);      
        fs.Close();
      }
      else {        
        Debug.Log("DownloadCompleteCallback (data == null): " + e.Error);
      }
    }
    catch(System.Exception exception) {
      Debug.Log("DownloadCompleteCallback: " + exception.Message);
    }
  }

as funktioniert wunderbar. Nur leider sind die Werte e.TotalBytesToReceive -1 und entsprechend e.ProgressPercentage 0. am Webserver kann es nicht liegen, dass dieser die Daten nicht übermittelt, denn mit Filezilla wird ein Fortschritt angezeigt.

Muss ich da noch irgendwas beachten oder wo mache ich da noch einen Fehler?

Crosspost in der DP: www.delphipraxis.net...und-fortschritt.html
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 20.06.11 10:49 
Ich denke einmal dieser Teil aus der Doku ist für dich entscheidend:
Doku zu WebClient.DownloadProgressChanged-Ereignis hat folgendes geschrieben:
Bei einer Dateiübertragung mit passivem FTP wird immer ein Fortschrittsprozentsatz von 0 (null) angezeigt, da der Server keine Dateigröße sendet. Um den Fortschritt anzuzeigen, können Sie die FTP-Verbindung durch Überschreiben der virtuellen GetWebRequest-Methode in eine aktive Verbindung ändern:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
internal class MyWebClient:WebClient{
        protected override WebRequest GetWebRequest(Uri address) {
            FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
            req.UsePassive = false;
            return req;
        }
    }
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.06.11 11:01 
Mist, dann habe ich den Hinweis übersehen. Aber ich habe Probleme das in meinen bestehenden Code einzubauen. Kannst du mir da noch mal helfen?

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
using UnityEngine;
using System;
using System.Collections;
using System.IO;
using System.Net;

public class NewBehaviourScript2 : MonoBehaviour {
  
  WebClient ftpRequest;
  private string progressOutput = "";
  private string user = "l3s11195";
  private string password = "!BSfBtrp#";
  private string filename = "BWL.pdf";
  private string sourceFilePath = "ftp://michael-puff.de/html/Archiv/Ausbildung_FIAE";  //http://michael-puff.de/Archiv/Ausbildung_FIAE/BWL.pdf
  private string destFilePath = "C:\\Dokumente und Einstellungen\\mp\\Eigene Dateien";
  private long bytesReceived;

  internal class ???.WebClient{
        protected override WebRequest GetWebRequest(Uri address) {
            FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
            req.UsePassive = false;
            return req;
        }
    }


Das ist erst mal so vorgegeben von Unity3D Engine.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 20.06.11 12:00 
Du kannst MyWebClient da stehen lassen oder etwas anderes, entscheidend ist, dass du statt new WebClient dann schreibst new MyWebClient oder ähnliches. ;-)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.06.11 12:02 
Ah, jetzt verstehe ich. Ich kann es zwar noch nicht in Worte fassen, aber es kommt langsam.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.06.11 12:15 
Jetzt scheine ich aber keine Verbindung zum Server zu bekommen:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
using UnityEngine;
using System;
using System.Collections;
using System.IO;
using System.Net;


public class NewBehaviourScript2 : MonoBehaviour {

    internal class MyWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
            req.UsePassive = false;
            return req;
        }
    }

  MyWebClient ftpRequest;
  private string progressOutput = "";
  private string user = "???";
  private string password = "???";
  private string filename = "BWL.pdf";
  private string sourceFilePath = "ftp://michael-puff.de/html/Archiv/Ausbildung_FIAE";
  private string destFilePath = "C:\\Dokumente und Einstellungen\\mp\\Eigene Dateien";
  private long bytesReceived;  
  
  // Use this for initialization
  void Start () {      
    ftpRequest = new MyWebClient();
    Debug.Log("Start: " + sourceFilePath + "/" + filename);
    System.Uri uri = new System.Uri(sourceFilePath + "/" + filename);
    try {
      ftpRequest.Credentials = new NetworkCredential(user, password);
      ftpRequest.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
      ftpRequest.DownloadDataCompleted += new DownloadDataCompletedEventHandler(DownloadCompleteCallback);
      ftpRequest.DownloadDataAsync(uri);          
    }
    catch(System.Exception e) {            
      Debug.Log("Start: " + e.Message);
    }
  }
  
  void DownloadProgressCallback(System.Object sender, DownloadProgressChangedEventArgs e) {    
    bytesReceived += e.BytesReceived;    
    progressOutput = String.Format("{0:N} Bytes von {1:N} Bytes empfangen ({2:D}%)", bytesReceived, e.TotalBytesToReceive, e.ProgressPercentage);
    Debug.Log(progressOutput);
  }
  
  void DownloadCompleteCallback(System.Object sender, DownloadDataCompletedEventArgs e) {    
    try {
      byte[] data = (byte[])e.Result;            
      if (data != null) {
        Debug.Log("DownloadCompleteCallback: " + destFilePath + "\\" + filename);
        FileStream fs = new FileStream(destFilePath + "\\" + filename, FileMode.Create);      
        fs.Write(data, 0, data.Length);          
        fs.Close();
      }
      else {        
        Debug.Log("DownloadCompleteCallback (data == null): " + e.Error);
      }
    }
    catch(System.Exception exception) {
      Debug.Log("DownloadCompleteCallback: " + exception.Message);
    }
  }
}

Selbst wenn ich req.UsePassive = false; auf true setzte. An aktiv oder passiv kann es also nicht liegen. Die genau Fehlermeldung lautet:
Zitat:
DownloadCompleteCallback (data == null): System.Net.WebException: An error occurred performing a WebClient request. ---> System.IO.IOException: Not connected
at System.Net.Sockets.NetworkStream..ctor (System.Net.Sockets.Socket socket, FileAccess access, Boolean owns_socket) [0x00000] in <filename unknown>:0
at System.Net.Sockets.NetworkStream..ctor (System.Net.Sockets.Socket socket, Boolean owns_socket) [0x00000] in <filename unknown>:0
at (wrapper remoting-invoke-with-check) System.Net.Sockets.NetworkStream:.ctor (System.Net.Sockets.Socket,bool)
at System.Net.FtpWebRequest.OpenDataConnection () [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.DownloadData () [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.ProcessMethod () [0x00000] in <filename unknown>:0
at System.Net.FtpWebRequest.ProcessRequest () [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Net.WebClient.DownloadDataCore (System.Uri address, System.Object userToken) [0x00000] in <filename unknown>:0
at System.Net.WebClient.<DownloadDataAsync>m__D (System.Object state) [0x00000] in <filename unknown>:0


Zuletzt bearbeitet von Luckie am Mo 20.06.11 12:34, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 20.06.11 12:30 
Ich schaue es mir heute Abend an. Im Moment bin ich bei der Arbeit, da habe ich natürlich nicht die Zeit. ;-)

Aber vielleicht antwortet ja auch einer von den .NET Cracks hier vorher. :D
Andreas L.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1703
Erhaltene Danke: 25

Windows Vista / Windows 10
Delphi 2009 Pro (JVCL, DragDrop, rmKlever, ICS, EmbeddedWB, DEC, Indy)
BeitragVerfasst: Mo 20.06.11 12:32 
@Luckie: Ich hoffe das ist nicht dein echtes Passwort:   private string password = "!BSfBtrp#"; :hair:
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.06.11 13:02 
Nein. ;)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 21.06.11 09:37 
Ich habe leider immer noch keinen Grund finden können, warum er jetzt sich jetzt nicht mehr verbindet.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 21.06.11 22:35 
Sorry, ich bin gestern nicht mehr dazu gekommen.

Ich habe es jetzt gerade ausprobiert (mit Visual Studio 2010 und Windows Forms mit .NET 4.0 als Target). Da funktioniert der Code 1:1 wie du ihn zuletzt gepostet hast. :nixweiss:

Womit arbeitest du? Also welcher Projekttyp, welche .NET Version, ...?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 21.06.11 23:18 
Gute Frage. Ich weiß es nicht. Das ist ein Script, welches vom Unity3D Spiele Engine ausgeführt wird. Keine Ahnung, ob das das installierte .Net Framework nutzt oder ob es ein eigenes mitbringt und dies veraltet ist. Ich weiß nur, dass es System.Console nicht unterstützt.

Gibt es eine Möglichkeit sich die nötigen Informationen von Hand vom FTP-Server zu holen und das dann selber auszurechnen?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 21.06.11 23:28 
Funktioniert denn die ursprüngliche Version noch? Also ohne die überschriebene WebClient-Klasse?

Ich habe gerade mal ein wenig getestet, egal ob ich für .NET 2.0, 3.0 oder 4.0 kompiliere und ausführe, es klappt.

// EDIT:
Sonst fällt mir nur ein die Verbindung selbst zu machen, z.B. über die API oder direkt über Sockets.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 21.06.11 23:55 
Ja, die ursprüngliche Version funktioniert. Aber es ist auch im Moment nicht so wichtig. Ist erst mal auch nur ein Proof-of-concept.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 22.06.11 12:47 
Das dürfte Mono sein, WebClient.<DownloadDataAsync>m__D existiert in der CLR gar nicht. In der History auf Github sehe ich keinen Hinweis auf gefixte Bugs, zu alt kann es also auch nicht sein. Was passiert denn bei einem hamrlosen
ausblenden C#-Quelltext
1:
2:
3:
4:
        protected override WebRequest GetWebRequest(Uri address)
        {
            return (FtpWebRequest)base.GetWebRequest(address);
        }
?
Auch wenn die Property mindestens genauso harmlos ausschaut :gruebel: ...

_________________
>λ=
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 23.06.11 09:23 
Ja, ich habe im Unity3D Ordner einen Ordner Mono gefunden. Ich werde das am Montag mal ausprobieren.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 27.06.11 10:36 
Wenn ich den Code von Kha nehme, bekomme ich folgende Fehlermeldung:
Zitat:
Assets/FTPWebClientDownload.cs(13,35): error CS0115: `FTPWebClientDownload.GetWebRequest(System.Uri)' is marked as an override but no suitable method found to override

Zeile 13 ist die Zeile protected override WebRequest GetWebRequest(Uri address) {.

Und in der Entwicklungsumgebung wird mir angezeigt, dass
Zitat:
"UnityEngine.MonoBehaviour" enthält keine Definition für "GetWebRequest"
.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 27.06.11 18:28 
Ich meinte schon weiterhin innerhalb von MyWebClient ;) .

_________________
>λ=
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 27.06.11 23:28 
Ach so, morgen mal ausprobieren.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 28.06.11 09:53 
Ich habe es jetzt so:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
    internal class MyWebClient : WebClient {
        protected override WebRequest GetWebRequest(Uri address) {
            return (FtpWebRequest)base.GetWebRequest(address);
        }
    }

So kompiliert und läuft es zwar, aber ich bekomme immer noch keine Werte für die Gesamtgröße und den Fortschritt.