private void OnDownloadProgressChanged(object source, DownloadStatusChangedEventArgs a)
        {
            long fileSize      = 0;
            long bytesReceived = a.BytesReceived;

            // get total filesize of *all* the files of the InstallComponent
            // then get the total download progress instead of the progress per file
            // and change the progressbar
            // if it fails for whatever reason, ignore and fallback to given percentage
            try
            {
                // this is rather hacky sadly
                // since what if i.e part 2 isn't downloaded but part 3 is?
                // it'll display it incorrectly,
                // we don't care for now
                // since users wont touch the files (I hope..)
                for (int i = 0; i < a.CurrentComponentDownloadIndex; i++)
                {
                    bytesReceived += a.CurrentComponent.Urls[i].FileSize;
                }

                // add each filesize to fileSize
                foreach (UrlInfo urlInfo in a.CurrentComponent.Urls)
                {
                    fileSize += urlInfo.FileSize;
                }

                // since we only accept int as argument,
                // just convert bytes to MB
                // since we'll be going over the maximum int value
                // if we don't do this
                int megaBytesReceived   = (int)(bytesReceived / 1024 / 1024);
                int fileSizeInMegaBytes = (int)(fileSize / 1024 / 1024);

                ChangeProgressBarValue(megaBytesReceived, fileSizeInMegaBytes);
                ChangeProgressLabel($"{megaBytesReceived} MiB / {fileSizeInMegaBytes} MiB @ {GetAverageDownloadSpeed((bytesReceived / 1024), a.CurrentComponent)} KiB/s");
            }
            catch (Exception)
            {
                // ignore
            }
        }
    public bool stop = true;     // by default stop is true
    // add option get current download speed
    public void DownloadFile(string DownloadLink, string Path)
    {
        stop = false;     // always set this bool to false, everytime this method is called
        long       ExistingLength = 0;
        FileStream saveFileStream;

        if (File.Exists(Path))
        {
            FileInfo fileInfo = new FileInfo(Path);
            ExistingLength = fileInfo.Length;
        }
        if (ExistingLength > 0)
        {
            saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
        }
        else
        {
            saveFileStream = new FileStream(Path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
        }
        var request = (HttpWebRequest)HttpWebRequest.Create(DownloadLink);

        request.Proxy = null;
        request.AddRange(ExistingLength);
        try
        {
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                long FileSize = ExistingLength + response.ContentLength; //response.ContentLength gives me the size that is remaining to be downloaded
                bool downloadResumable;                                  // need it for sending empty progress
                if ((int)response.StatusCode == 206)
                {
                    Console.WriteLine("Resumable");
                    var downloadStatusArgs = new DownloadStatusChangedEventArgs();
                    downloadResumable = true;
                    downloadStatusArgs.ResumeSupported = downloadResumable;
                    OnDownloadStatusChanged(downloadStatusArgs);
                }
                else     // sometimes a server that supports partial content will lose its ability to send partial content(weird behavior) and thus the download will lose its resumability
                {
                    Console.WriteLine("Resume Not Supported");
                    ExistingLength = 0;
                    var downloadStatusArgs = new DownloadStatusChangedEventArgs();
                    downloadResumable = false;
                    downloadStatusArgs.ResumeSupported = downloadResumable;
                    OnDownloadStatusChanged(downloadStatusArgs);
                    // restart downloading the file from the beginning because it isn't resumable
                    // if this isn't done, the method downloads the file from the beginning and starts writing it after the previously half downloaded file, thus increasing the filesize and corrupting the downloaded file
                    saveFileStream.Dispose();                                                                                       // dispose object to free it for the next operation
                    File.WriteAllText(Path, string.Empty);                                                                          // clear the contents of the half downloaded file that can't be resumed
                    saveFileStream = saveFileStream = new FileStream(Path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); // reopen it for writing
                }
                using (var stream = response.GetResponseStream())
                {
                    byte[] downBuffer    = new byte[4096];
                    int    byteSize      = 0;
                    long   totalReceived = byteSize + ExistingLength;
                    //var sw = new Stopwatch();
                    while ((byteSize = stream.Read(downBuffer, 0, downBuffer.Length)) > 0)
                    {
                        //sw.Reset();
                        //sw.Start();
                        saveFileStream.Write(downBuffer, 0, byteSize);
                        totalReceived += byteSize;
                        var args = new DownloadProgressChangedEventArgs();
                        args.BytesReceived       = totalReceived;
                        args.TotalBytesToReceive = FileSize;
                        if (downloadResumable == true)
                        {
                            args.ProgressPercentage = ((float)totalReceived / (float)FileSize) * 100;
                        }
                        else
                        {
                            args.ProgressPercentage = 0;
                        }
                        //args.CurrentSpeed = ;
                        OnDownloadProgressChanged(args);
                        //sw.Stop();
                        if (stop == true)
                        {
                            return;
                        }
                    }
                }
            }
            var completedArgs = new EventArgs();
            OnDownloadCompleted(completedArgs);
            saveFileStream.Dispose();
        }
        catch (WebException e)
        {
            string filename = System.IO.Path.GetFileName(Path);
            Console.WriteLine(e.Message);
            saveFileStream.Dispose();
            return;     //not needed because this is the last line of the method, but let's keep it here
        }
    }
        private void CurrentDownload_ResumablityChanged(object sender, DownloadStatusChangedEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
            Status.Text = "Receiving data...";

                if (e.ResumeSupported)
                {
                    ResumeCapability.Text = "Yes";
                }
                else
                {
                    ResumeCapability.Foreground = System.Windows.Media.Brushes.Red;
                    ResumeCapability.Text = "No";
                }
            });
        }
 private void CurrentDownload_Error(object sender, DownloadStatusChangedEventArgs e)
 {
     MessageBox.Show(e.ErrorMessage + "\nPlease check your internet connection!", downloadData.FileName);
     Dispatcher.Invoke(() =>
     {
         Close(); // HACK this only works once, the second time the messagebox is displayed it fails to close the window
     });
 }
Exemple #5
0
        private void m_OnDownloadStatusChanged(object sender, DownloadStatusChangedEventArgs e)
        {
            var _resource = e.DownloadResource.ResourceInfo;

            if (_resource == null)
            {
                return;
            }

            switch (e.DownloadStatus)
            {
            case DownloadStatus.NotStart:
            case DownloadStatus.WaitForDownload:
                break;

            case DownloadStatus.Downloading:
                OnUpdateStatusCallBack.Invoke(this, e);
                break;

            case DownloadStatus.DownloadPause:
                LogInstance.Instance.LogInfo($"{ControlerName} ResourceID:[{_resource.ResourceID}], LocalFileName:[{_resource.LocalFileName}] download pause.");

                OnUpdateStatusCallBack.Invoke(this, e);
                FireBeginNextDownloadResource(_resource);
                break;

            case DownloadStatus.DownloadFailed_FileNotExist:
                LogInstance.Instance.LogInfo($"{ControlerName} ResourceID:[{_resource.ResourceID}], LocalFileName:[{_resource.LocalFileName}] download File Not Exist.");
                OnUpdateStatusCallBack.Invoke(this, e);
                FireBeginNextDownloadResource(_resource);
                break;

            case DownloadStatus.DownloadSuccess:
                LogInstance.Instance.LogInfo($"{ControlerName} ResourceID:[{_resource.ResourceID}], LocalFileName:[{_resource.LocalFileName}] download finished, begin check md5.");
                OnUpdateStatusCallBack.Invoke(this, new DownloadStatusChangedEventArgs(e.DownloadResource, DownloadStatus.MD5Checking));

                // md5 check maybe spend long time
                if (e.DownloadResource.CheckMD5())
                {
                    LogInstance.Instance.LogInfo($"{ControlerName} ResourceID:[{_resource.ResourceID}], LocalFileName:[{_resource.LocalFileName}] md5 check success.");
                    OnUpdateStatusCallBack.Invoke(this, new DownloadStatusChangedEventArgs(e.DownloadResource, DownloadStatus.DownloadSuccess));
                }
                else
                {
                    LogInstance.Instance.LogInfo($"{ControlerName} ResourceID:[{_resource.ResourceID}], LocalFileName:[{_resource.LocalFileName}] md5 check failed.");
                    OnUpdateStatusCallBack.Invoke(this, new DownloadStatusChangedEventArgs(e.DownloadResource, DownloadStatus.DownloadFailed_MD5CheckFailed));
                }

                FireBeginNextDownloadResource(_resource);
                break;

            case DownloadStatus.DownloadFailed:
                LogInstance.Instance.LogInfo($"{ControlerName} ResourceID:{_resource.ResourceID}, LocalFileName:{_resource.LocalFileName} download failed.");
                OnUpdateStatusCallBack.Invoke(this, e);

                FireBeginNextDownloadResource(_resource);
                break;

            default:
                break;
            }
        }