Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/duplicati/duplicati.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Duplicati/Library/AutoUpdater/UpdaterManager.cs')
-rw-r--r--Duplicati/Library/AutoUpdater/UpdaterManager.cs113
1 files changed, 113 insertions, 0 deletions
diff --git a/Duplicati/Library/AutoUpdater/UpdaterManager.cs b/Duplicati/Library/AutoUpdater/UpdaterManager.cs
index 6328d461e..6f0857cf8 100644
--- a/Duplicati/Library/AutoUpdater/UpdaterManager.cs
+++ b/Duplicati/Library/AutoUpdater/UpdaterManager.cs
@@ -18,6 +18,8 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
namespace Duplicati.Library.AutoUpdater
{
@@ -34,6 +36,11 @@ namespace Duplicati.Library.AutoUpdater
public static class UpdaterManager
{
+ /// <summary>
+ /// The magic exit code that signals an update has been installed and that the app should restart
+ /// </summary>
+ public const int MAGIC_EXIT_CODE = 126;
+
private static readonly System.Security.Cryptography.RSACryptoServiceProvider SIGN_KEY = AutoUpdateSettings.SignKey;
private static readonly string[] MANIFEST_URLS = AutoUpdateSettings.URLs;
private static readonly string APPNAME = AutoUpdateSettings.AppName;
@@ -1002,8 +1009,114 @@ namespace Duplicati.Library.AutoUpdater
}
}
+ private static KeyValuePair<string, UpdateInfo> GetBestUpdateVersion(bool forcecheck = false)
+ {
+ if (forcecheck)
+ m_hasUpdateInstalled = null;
+
+ // Check if there are updates installed, otherwise use current
+ KeyValuePair<string, UpdateInfo> best = new KeyValuePair<string, UpdateInfo>(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, SelfVersion);
+ if (HasUpdateInstalled)
+ best = m_hasUpdateInstalled.Value;
+
+ if (INSTALLDIR != null && System.IO.File.Exists(System.IO.Path.Combine(INSTALLDIR, CURRENT_FILE)))
+ {
+ try
+ {
+ var current = System.IO.File.ReadAllText(System.IO.Path.Combine(INSTALLDIR, CURRENT_FILE)).Trim();
+ if (!string.IsNullOrWhiteSpace(current))
+ {
+ var targetfolder = System.IO.Path.Combine(INSTALLDIR, current);
+ var currentmanifest = ReadInstalledManifest(targetfolder);
+ if (currentmanifest != null && TryParseVersion(currentmanifest.Version) > TryParseVersion(best.Value.Version) && VerifyUnpackedFolder(targetfolder, currentmanifest))
+ best = new KeyValuePair<string, UpdateInfo>(targetfolder, currentmanifest);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (OnError != null)
+ OnError(ex);
+ }
+ }
+
+ return best;
+ }
+
+ public static bool IsRunningInUpdateEnvironment => !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(string.Format(BASEINSTALLDIR_ENVNAME_TEMPLATE, APPNAME)));
+
public static int RunFromMostRecent(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
{
+ return RunFromMostRecentSpawn(method, cmdargs, defaultstrategy);
+ }
+
+ public static int RunFromMostRecentSpawn(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
+ {
+ // If the update is disabled, go straight in
+ //if (DISABLE_UPDATE_DOMAIN)
+ // return RunMethod(method, cmdargs);
+
+ // If we are not the primary entry, just execute
+ if (IsRunningInUpdateEnvironment)
+ {
+ int r = 0;
+ WrapWithUpdater(defaultstrategy, () => {
+ r = RunMethod(method, cmdargs);
+ });
+
+ return r;
+ }
+
+ var args = Environment.CommandLine;
+ var app = Environment.GetCommandLineArgs().First();
+ args = args.Substring(app.Length);
+
+ if (!Path.IsPathRooted(app))
+ app = Path.Combine(InstalledBaseDir, app);
+
+ var executable = Path.GetFileName(app);
+
+ while (true)
+ {
+ var best = GetBestUpdateVersion(true);
+ var folder = best.Key;
+
+ var pi = new System.Diagnostics.ProcessStartInfo(Path.Combine(folder, executable), args)
+ {
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardError = true,
+ RedirectStandardInput = true,
+ RedirectStandardOutput = true,
+ ErrorDialog = false,
+ };
+ pi.EnvironmentVariables.Clear();
+
+ var cur = Environment.GetEnvironmentVariables();
+ foreach (var e in cur.Keys)
+ if (e is string)
+ pi.EnvironmentVariables[(string)e] = cur[(string)e] as string;
+
+ pi.EnvironmentVariables[string.Format(BASEINSTALLDIR_ENVNAME_TEMPLATE, APPNAME)] = InstalledBaseDir;
+ pi.EnvironmentVariables["LOCALIZATION_FOLDER"] = InstalledBaseDir;
+
+ var proc = System.Diagnostics.Process.Start(pi);
+ var tasks = Task.WhenAll(
+ Console.OpenStandardInput().CopyToAsync(proc.StandardInput.BaseStream),
+ proc.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput()),
+ proc.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError())
+ );
+
+ proc.WaitForExit();
+ tasks.Wait(1000);
+
+ if (proc.ExitCode != MAGIC_EXIT_CODE)
+ return proc.ExitCode;
+ }
+
+ }
+
+ public static int RunFromMostRecentAppDomain(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
+ {
// If the update is disabled, go straight in
if (DISABLE_UPDATE_DOMAIN)
return RunMethod(method, cmdargs);