static UpdateInfoFileContent ReadUpdateInfoFile(string fileName)
        {
            var retVal = new UpdateInfoFileContent();

            if (File.Exists(fileName))
            {
                try
                {
                    var        updateInfoDoc = XDocument.Load(fileName);
                    XAttribute attr;
                    if ((attr = updateInfoDoc.Root.Attribute("binaries-etag")) != null)
                    {
                        retVal.BinariesETag = attr.Value;
                    }
                    DateTime lastChecked;
                    if ((attr = updateInfoDoc.Root.Attribute("last-check-timestamp")) != null)
                    {
                        if (DateTime.TryParseExact(attr.Value, "o", null,
                                                   System.Globalization.DateTimeStyles.AssumeUniversal | System.Globalization.DateTimeStyles.AdjustToUniversal, out lastChecked))
                        {
                            retVal.LastCheckTimestamp = lastChecked;
                        }
                    }
                    if ((attr = updateInfoDoc.Root.Attribute("last-check-error")) != null)
                    {
                        retVal.LastCheckError = attr.Value;
                    }
                }
                catch
                {
                }
            }
            return(retVal);
        }
        void SetLastUpdateCheckInfo(UpdateInfoFileContent updateInfoFileContent)
        {
            LastUpdateCheckInfo info = null;

            if (updateInfoFileContent.LastCheckTimestamp.HasValue)
            {
                info = new LastUpdateCheckInfo()
                {
                    When         = updateInfoFileContent.LastCheckTimestamp.Value,
                    ErrorMessage = updateInfoFileContent.LastCheckError
                }
            }
            ;
            lock (sync)
            {
                lastUpdateResult = info;
            }
            FireChangedEvent();
        }

        void SetState(AutoUpdateState state)
        {
            lock (sync)
            {
                if (this.state == state)
                {
                    return;
                }
                this.state = state;
            }
            trace.Info("autoupdater state -> {0}", state);
            FireChangedEvent();
        }
Exemple #3
0
        void SetLastUpdateCheckInfo(UpdateInfoFileContent updateInfoFileContent)
        {
            LastUpdateCheckInfo info = null;

            if (updateInfoFileContent.LastCheckTimestamp.HasValue)
            {
                info = new LastUpdateCheckInfo(updateInfoFileContent.LastCheckTimestamp.Value, updateInfoFileContent.LastCheckError);
            }
            lock (sync)
            {
                lastUpdateResult = info;
            }
            FireChangedEvent();
        }
        static void WriteUpdateInfoFile(string fileName, UpdateInfoFileContent updateInfoFileContent)
        {
            var doc = new XDocument(new XElement("root"));

            if (updateInfoFileContent.BinariesETag != null)
            {
                doc.Root.Add(new XAttribute("binaries-etag", updateInfoFileContent.BinariesETag));
            }
            if (updateInfoFileContent.LastCheckTimestamp.HasValue)
            {
                doc.Root.Add(new XAttribute("last-check-timestamp", updateInfoFileContent.LastCheckTimestamp.Value.ToString("o")));
            }
            if (updateInfoFileContent.LastCheckError != null)
            {
                doc.Root.Add(new XAttribute("last-check-error", updateInfoFileContent.LastCheckError));
            }
            doc.Save(fileName);
        }
Exemple #5
0
        async Task Worker()
        {
            try
            {
                await Task.Delay(Constants.initialWorkerDelay, workerCancellationToken);

                HandlePastUpdates(workerCancellationToken);

                SetState(AutoUpdateState.Idle);

                for (;;)
                {
                    var appUpdateInfoFileContent = UpdateInfoFileContent.Read(updateInfoFilePath);
                    var installationUpdateKey    = factory.CreateUpdateKey(
                        appUpdateInfoFileContent.BinariesETag,
                        pluginsManager.InstalledPlugins.ToDictionary(
                            p => p.Id,
                            p => UpdateInfoFileContent.Read(Path.Combine(p.PluginDirectory, Constants.updateInfoFileName)).BinariesETag
                            )
                        );

                    SetLastUpdateCheckInfo(appUpdateInfoFileContent);

                    await IdleUntilItsTimeToCheckForUpdate(appUpdateInfoFileContent.LastCheckTimestamp);

                    SetState(AutoUpdateState.Checking);

                    var appCheckResult = await CheckForUpdate(appUpdateInfoFileContent.BinariesETag);

                    if (appCheckResult.Status == DownloadUpdateResult.StatusCode.Failure)
                    {
                        continue;
                    }

                    var requiredPlugins = await GetRequiredPlugins(pluginsManager, workerCancellationToken);

                    var requiredUpdateKey = factory.CreateUpdateKey(
                        appCheckResult.ETag,
                        requiredPlugins.ToDictionary(p => p.Id, p => p.IndexItem.ETag)
                        );

                    var nullUpdateKey = factory.CreateNullUpdateKey();

                    bool requiredUpdateIsSameAsAlreadyInstalled = requiredUpdateKey.Equals(installationUpdateKey);
                    trace.Info("Comparing required update key '{0}' with already installed '{1}': {2}", requiredUpdateKey, installationUpdateKey, requiredUpdateIsSameAsAlreadyInstalled);
                    if (requiredUpdateIsSameAsAlreadyInstalled)
                    {
                        requiredUpdateKey = nullUpdateKey;
                    }

                    if (!requiredUpdateKey.Equals(currentPendingUpdate?.Key ?? nullUpdateKey))
                    {
                        if (currentPendingUpdate != null)
                        {
                            await currentPendingUpdate.Dispose();

                            currentPendingUpdate = null;
                        }
                        if (!requiredUpdateKey.Equals(nullUpdateKey))
                        {
                            currentPendingUpdate = await factory.CreatePendingUpdate(
                                requiredPlugins,
                                managedAssembliesPath,
                                ComposeUpdateLogFileName(),
                                workerCancellationToken
                                );

                            trace.Info("Created new pending update with key '{0}'", currentPendingUpdate.Key);
                        }
                    }

                    if (currentPendingUpdate != null)
                    {
                        SetState(AutoUpdateState.WaitingRestart);
                    }
                    else
                    {
                        SetState(AutoUpdateState.Idle);
                    }
                }
            }
            catch (TaskCanceledException)
            {
                trace.Info("autoupdater worker cancelled");
            }
            catch (OperationCanceledException)
            {
                trace.Info("autoupdater worker cancelled");
            }
            catch (BadInstallationDirException e)
            {
                trace.Error(e, "bad installation directory detected");
                SetState(AutoUpdateState.FailedDueToBadInstallationDirectory);
                throw;
            }
            catch (Exception e)
            {
                trace.Error(e, "autoupdater worker failed");
                SetState(AutoUpdateState.Failed);
                telemetry.ReportException(e, "autoupdater worker");
                throw;
            }
        }