public DownloadStatusChangedEventArgs(long bytesReceived, int?progressPercentage,
                                       InstallerComponent currentComponent,
                                       int currentComponentDownloadIndex)
 {
     this.BytesReceived                 = bytesReceived;
     this.ProgressPercentage            = progressPercentage;
     this.CurrentComponent              = currentComponent;
     this.CurrentComponentDownloadIndex = currentComponentDownloadIndex;
 }
        /// <summary>
        /// Downloads DownloadComponent in directory
        /// </summary>
        public void DownloadComponent(ref InstallerComponent component, string directory)
        {
            ComponentDownloadIndex = -1;
            CurrentComponent       = component;

            // loop over each URL and download it
            for (int i = 0; i < component.Urls.Count; i++)
            {
                UrlInfo urlInfo = component.Urls[i];

                ComponentDownloadIndex++;

                // if it's an AppVeyor Url,
                // use the AppVeyor API to get file information
                // and change urlInfo according to that
                if (IsAppVeyorUrl(urlInfo.Url))
                {
                    try
                    {
                        urlInfo = AppVeyorUrlInfo(urlInfo);
                    }
                    catch (Exception e)
                    {
                        Exception = e;
                        Failed    = true;
                        return;
                    }

                    // also update the actual InstallerComponent
                    component.Urls[0] = urlInfo;
                    CurrentComponent  = component;
                }

                string url = urlInfo.Url;

                string file = null;
                if (urlInfo.FileName != null)
                {
                    file = Path.Combine(directory, urlInfo.FileName);
                }

                string hash = urlInfo.FileHash;

                // if the hash matches, skip it
                if (VerifyHash(file, hash, urlInfo.FileSize))
                {
                    continue;
                }

                // try to download the file using WebClient
                // also verify the hash when it's done.
                // since we also want the events to work
                // we'll download it async
                // and wait for the WebClient to be done
                try
                {
                    // since windows 7 is throwing this exception:
                    // "The request was aborted: Could not create SSL/TLS secure channel."
                    // we know that it's trying to use a wrong encryption type(possibly tls 1)
                    // so we'll configure it to use *everything* except tls 1
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

                    Client.DownloadFileAsync(new Uri(url), file);

                    // we use Thread.Sleep here because
                    // Thread.Yield has high cpu usage
                    while (Client.IsBusy)
                    {
                        Thread.Sleep(10);
                    }

                    Failed = !VerifyHash(file, hash, urlInfo.FileSize);
                }
                catch (Exception e)
                {
                    Exception = e;
                    Failed    = true;
                }

                // abort when failed
                if (Failed)
                {
                    return;
                }
            }
        }
        /// <summary>
        /// Downloads DownloadComponent in directory
        /// </summary>
        public void DownloadComponent(InstallerComponent component, string directory)
        {
            ComponentDownloadIndex = -1;
            CurrentComponent       = component;

            // loop over each URL and download it
            foreach (UrlInfo urlInfo in component.Urls)
            {
                ComponentDownloadIndex++;

                string url  = urlInfo.Url;
                string file = Path.Combine(directory, urlInfo.FileName);
                string hash = urlInfo.FileHash;

                // if the hash matches, skip it
                if (VerifyHash(file, hash))
                {
                    continue;
                }

                // if the URL is a Google Drive URL,
                // download it using the Google API
                // and continue
                if (IsGoogleDriveUrl(url))
                {
                    DownloadGoogleDriveFile(url, file, hash);

                    // abort when failed
                    if (Failed)
                    {
                        return;
                    }

                    continue;
                }

                // try to download the file using WebClient
                // also verify the hash when it's done.
                // since we also want the events to work
                // we'll download it async
                // and wait for the WebClient to be done
                try
                {
                    // since windows 7 is throwing this exception:
                    // "The request was aborted: Could not create SSL/TLS secure channel."
                    // we know that it's trying to use a wrong encryption type(possibly tls 1)
                    // so we'll configure it to use *everything* except tls 1
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

                    Client.DownloadFileAsync(new Uri(url), file);

                    // we use Thread.Sleep here because
                    // Thread.Yield has high cpu usage
                    while (Client.IsBusy)
                    {
                        Thread.Sleep(10);
                    }

                    Failed = !VerifyHash(file, hash);
                }
                catch (Exception e)
                {
                    Exception = e;
                    Failed    = true;
                }

                // abort when failed
                if (Failed)
                {
                    return;
                }
            }
        }