コード例 #1
0
        /// <summary>
        /// Gathers a list of files to download for the update.
        /// </summary>
        private List <RemoteFileInfo> GatherFilesToDownload(string buildPath,
                                                            string downloadDirectory)
        {
            List <RemoteFileInfo> filesToDownload = new List <RemoteFileInfo>();

            // This could be multithreaded later on for faster processing,
            // calculating the SHA1 hashes can take a lot of time

            for (int i = 0; i < remoteBuildInfo.FileInfos.Count; i++)
            {
                var remoteFileInfo = remoteBuildInfo.FileInfos[i];

                UpdateProgressChanged?.Invoke(this, new UpdateProgressEventArgs(
                                                  UpdateProgressState.PREPARING, 0,
                                                  (int)(i / (double)remoteBuildInfo.FileInfos.Count * 100.0), string.Empty));

                if (!File.Exists(buildPath + remoteFileInfo.FilePath))
                {
                    if (!File.Exists(downloadDirectory + remoteFileInfo.FilePath))
                    {
                        UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " doesn't exist, adding it to the download queue.");
                        filesToDownload.Add(remoteFileInfo);
                    }
                    else if (!HashHelper.FileHashMatches(downloadDirectory + remoteFileInfo.FilePath,
                                                         remoteFileInfo.UncompressedHash))
                    {
                        UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " exists in the " +
                                          "temporary directory, but it's different from the remote version. Adding it to the download queue.");
                        filesToDownload.Add(remoteFileInfo);
                    }
                }
                else
                {
                    if (!HashHelper.FileHashMatches(buildPath + remoteFileInfo.FilePath, remoteFileInfo.UncompressedHash))
                    {
                        UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " is different from the " +
                                          "remote version, adding it to the download queue.");
                        filesToDownload.Add(remoteFileInfo);
                    }
                    else
                    {
                        UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " is up to date.");
                    }
                }
            }

            return(filesToDownload);
        }
コード例 #2
0
        private void VerifyFiles()
        {
            while (true)
            {
                IndexedRemoteFileInfo indexedFileInfo;

                if (stopped)
                {
                    break;
                }

                lock (locker)
                {
                    indexedFileInfo = filesToCheck[0];
                }

                RemoteFileInfo fileInfo = indexedFileInfo.FileInfo;

                bool checkFileHash = true;

                if (fileInfo.Compressed)
                {
                    try
                    {
                        CompressionHelper.DecompressFile(downloadDirectory + fileInfo.GetFilePathWithCompression(),
                                                         downloadDirectory + fileInfo.FilePath);
                        File.Delete(downloadDirectory + fileInfo.GetFilePathWithCompression());
                    }
                    catch (Exception ex)
                    {
                        // The SevenZip compressor doesn't define what exceptions
                        // it might throw, so we'll just catch them all

                        UpdaterLogger.Log("Decompressing file " + fileInfo.FilePath + " failed! Message: " + ex.Message);
                        VerificationFailed?.Invoke(this, new IndexEventArgs(indexedFileInfo.Index));
                        queueReady    = false;
                        checkFileHash = false;
                    }
                }

                if (checkFileHash)
                {
                    if (!HashHelper.FileHashMatches(downloadDirectory + fileInfo.FilePath, fileInfo.UncompressedHash))
                    {
                        UpdaterLogger.Log("File " + fileInfo.FilePath + " failed verification!");
                        VerificationFailed?.Invoke(this, new IndexEventArgs(indexedFileInfo.Index));
                        queueReady = false;
                    }
                    else
                    {
                        UpdaterLogger.Log("File " + fileInfo.FilePath + " passed verification.");
                    }
                }

                bool waitingForWork = false;

                lock (locker)
                {
                    filesToCheck.RemoveAt(0);

                    waitingForWork = filesToCheck.Count == 0;

                    waitHandle.Reset();

                    if (queueReady && waitingForWork)
                    {
                        Completed?.Invoke(this, EventArgs.Empty);
                        break;
                    }

                    //if (stopped)
                    //{
                    //    filesToCheck.Clear();
                    //    break;
                    //}
                }

                if (waitingForWork)
                {
                    waitHandle.WaitOne();
                }
            }

            lock (locker)
            {
                waitHandle.Dispose();
                waitHandle = null;
            }

            // We could also dispose of verifierTask, but it sounds like we don't need to bother
            // https://blogs.msdn.microsoft.com/pfxteam/2012/03/25/do-i-need-to-dispose-of-tasks/
            // In case we'd still want to do it, it'd be safest for this class to have a function
            // for disposing the task (maybe this class could implement IDisposable), and the
            // user of this class would then call it
        }