Ejemplo n.º 1
0
        public void UpdateWithWorker(BackgroundWorker worker)
        {
            Progress progress1 = new Progress(0, 3);
            Progress progress2 = new Progress();

            int bytesRead;
            byte[] buffer = new byte[4096];

            worker.ReportProgress(DisplayProgress1, progress1);

            // Download File List
            using (WebClient client = new WebClient())
            {
                worker.ReportProgress(DisplayProgressText1, "Downloading File List ...");
                worker.ReportProgress(DisplayProgressText2, String.Empty);
                string files;
                try
                {
                    files = client.DownloadString(FileListUrl);
                }
                catch (Exception e)
                {
                    throw new ApplicationException("Could not download file-list.\nDetails: " + e.Message, e);
                }
                progress1.Increment();
                worker.ReportProgress(DisplayProgress1, progress1);

                worker.ReportProgress(DisplayProgressText1, "Validating File List ...");
                worker.ReportProgress(DisplayProgressText2, String.Empty);
                Items.Clear();
                StringReader reader = new StringReader(files);
                string line = reader.ReadLine();
                while (line != null)
                {
                    string[] fragments = line.Split('\t');
                    UpdateItem item = new UpdateItem(m_RootPath);
                    if (fragments.Length >= 1)
                    {
                        item.FileName = fragments[0];
                        if (String.Equals(Path.GetFullPath(item.FileName), Path.GetFullPath(Application.ExecutablePath), StringComparison.InvariantCultureIgnoreCase))
                        {
                            item.TargetFileName = item.FileName + ".tmp";
                            SelfUpdateDetected = true;
                            SelfUpdateItem = item;
                        }
                        if (String.IsNullOrEmpty(item.FileName)) continue;
                        m_Items.Add(item);
                    }
                    if (fragments.Length >= 2)
                    {
                        item.Hash = fragments[1];
                    }
                    line = reader.ReadLine();
                }
                progress1.Increment();
                worker.ReportProgress(DisplayProgress1, progress1);

                if (worker.CancellationPending) return;

                progress2.Reset(0, Items.Count);
                worker.ReportProgress(DisplayProgress2, progress2);
                worker.ReportProgress(DisplayProgressText1, "Validating Files ...");
                Crc32Processor processor = new Crc32Processor();
                foreach (UpdateItem item in Items)
                {
                    if (worker.CancellationPending) return;
                    worker.ReportProgress(DisplayProgressText2, item.FullName);

                    if (File.Exists(item.FullName) == false)
                    {
                        item.CheckStatus = UpdateCheckStatus.NotExisiting;
                        item.IsUpdateRequired = true;
                    }
                    else
                    {
                        using (FileStream fs = File.OpenRead(item.FullName))
                        {
                            while (true)
                            {
                                bytesRead = fs.Read(buffer, 0, buffer.Length);
                                processor.Process(buffer, 0, bytesRead);
                                if (bytesRead != buffer.Length) break;
                            }
                        }
                        if (item.Hash != processor.Current.ToString("X8"))
                        {
                            item.CheckStatus = UpdateCheckStatus.HashMismatch;
                            item.IsUpdateRequired = true;
                        }
                        else
                        {
                            item.CheckStatus = UpdateCheckStatus.Ok;
                        }
                        processor.Reset();
                    }

                    progress2.Increment();
                    worker.ReportProgress(DisplayProgress2, progress2);
                }
                progress1.Increment();
                worker.ReportProgress(DisplayProgress1, progress1);

                worker.ReportProgress(DisplayProgressText1, "Downloading Files ...");
                foreach (UpdateItem item in Items)
                {
                    if (worker.CancellationPending) return;

                    if (item.IsUpdateRequired == false) continue;

                    string fileName = item.FileName;
                    if (fileName.StartsWith("./")) fileName = fileName.Substring(2);

                    using (Stream stream = client.OpenRead(WebPath.Combine(BaseUrl, fileName)))
                    {
                        // Create Directory If Missing
                        string directoryName = Path.GetDirectoryName(item.FullName);
                        if (Directory.Exists(directoryName) == false) Directory.CreateDirectory(directoryName);

                        using (FileStream outStream = File.Open(m_RootPath + item.TargetFileName, File.Exists(m_RootPath + item.TargetFileName) ? FileMode.Truncate : FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            int contentLength = Int32.Parse(client.ResponseHeaders[HttpResponseHeader.ContentLength]);
                            progress2.Reset(0, contentLength);
                            worker.ReportProgress(DisplayProgress2, progress2);

                            int totalBytesRead = 0;
                            while (true)
                            {
                                worker.ReportProgress(DisplayProgressText2, String.Format("Downloading: {0} - {1:N0}/{2:N0}", fileName, totalBytesRead, contentLength));

                                bytesRead = stream.Read(buffer, 0, buffer.Length);
                                outStream.Write(buffer, 0, bytesRead);
                                totalBytesRead += bytesRead;

                                progress2.CurrentValue = totalBytesRead;
                                worker.ReportProgress(DisplayProgress2, progress2);

                                if (totalBytesRead >= contentLength) break;
                            }
                        }
                    }

                    // Validating File
                    if (String.IsNullOrEmpty(item.Hash) == false)
                    {
                        progress2.Reset();
                        worker.ReportProgress(DisplayProgressText2, String.Format("Validating: {0}", fileName));
                        using (FileStream fs = File.OpenRead(m_RootPath + item.TargetFileName))
                        {
                            while (true)
                            {
                                bytesRead = fs.Read(buffer, 0, buffer.Length);
                                processor.Process(buffer, 0, bytesRead);
                                if (bytesRead == 0) break;
                            }
                        }
                        if (item.Hash != processor.Current.ToString("X8"))
                        {
                            throw new ApplicationException("Downloaded file is invalid. Please restart launcher and repatch files.\nFile: " + m_RootPath + item.TargetFileName);
                        }
                        processor.Reset();
                    }
                }

                // Write Version File
                worker.ReportProgress(DisplayProgressText1, "Writing Version File ...");
                worker.ReportProgress(DisplayProgressText2, String.Empty);
                File.WriteAllText(VersionFileName, m_ServerVersionRawText, Encoding.Default);

                m_SuccessfulUpdated = true;
                m_CurrentVersionText = m_NewVersionText;
            }
        }