Changed the default for auto-update to be notify instead of install.
Added the --auto-update option to the commandline to allow automatic updates. Added a new Duplicati.Library.AutoUpdater.exe tool to work with updates, especially handy if the update breaks the install and for manual handling of updates.
This commit is contained in:
@@ -157,6 +157,10 @@
|
||||
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
|
||||
<Name>Duplicati.Library.Backend.OneDrive</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Localization\Duplicati.Library.Localization.csproj">
|
||||
<Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
|
||||
<Name>Duplicati.Library.Localization</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Duplicati.snk" />
|
||||
|
||||
@@ -21,6 +21,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Duplicati.Library.Localization.Short;
|
||||
|
||||
namespace Duplicati.CommandLine
|
||||
{
|
||||
@@ -230,10 +231,36 @@ namespace Duplicati.CommandLine
|
||||
Console.WriteLine(string.Format("Failed to delete temp file: {0}", path));
|
||||
});
|
||||
|
||||
|
||||
var autoupdate = Library.Utility.Utility.ParseBoolOption(options, "auto-update");
|
||||
options.Remove("auto-update");
|
||||
|
||||
if (knownCommands.ContainsKey(command))
|
||||
{
|
||||
return knownCommands[command](cargs, options, filter);
|
||||
var res = knownCommands[command](cargs, options, filter);
|
||||
|
||||
if (autoupdate)
|
||||
{
|
||||
var update = Library.AutoUpdater.UpdaterManager.LastUpdateCheckVersion;
|
||||
if (update == null)
|
||||
update = Library.AutoUpdater.UpdaterManager.CheckForUpdate();
|
||||
|
||||
if (update != null && update.Version != Library.AutoUpdater.UpdaterManager.SelfVersion.Version)
|
||||
{
|
||||
Console.WriteLine("Found update \"{0}\", downloading ...", update.Displayname);
|
||||
long lastpg = 0;
|
||||
Library.AutoUpdater.UpdaterManager.DownloadAndUnpackUpdate(update, f => {
|
||||
var npg = (long)(f*100);
|
||||
if (Math.Abs(npg - lastpg) >= 5 || (npg == 100 && lastpg != 100))
|
||||
{
|
||||
lastpg = npg;
|
||||
Console.WriteLine("Downloading {0}% ...", npg);
|
||||
}
|
||||
});
|
||||
Console.WriteLine("Update \"{0}\" ({1}) installed, using on next launch", update.Displayname, update.Version);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -281,6 +308,7 @@ namespace Duplicati.CommandLine
|
||||
new Library.Interface.CommandLineArgument("exclude", Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.ExcludeShort, Strings.Program.ExcludeLong),
|
||||
new Library.Interface.CommandLineArgument("control-files", Library.Interface.CommandLineArgument.ArgumentType.Boolean, Strings.Program.ControlFilesOptionShort, Strings.Program.ControlFilesOptionLong, "false"),
|
||||
new Library.Interface.CommandLineArgument("quiet-console", Library.Interface.CommandLineArgument.ArgumentType.Boolean, Strings.Program.QuietConsoleOptionShort, Strings.Program.QuietConsoleOptionLong, "false"),
|
||||
new Library.Interface.CommandLineArgument("auto-update", Library.Interface.CommandLineArgument.ArgumentType.Boolean, LC.L("Toggle automatic updates"), LC.L("Set this option if you prefer to have the commandline version automatically update"), "false"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ namespace Duplicati.Library.AutoUpdater
|
||||
private const string UPDATE_README = "AutoUpdateFolderReadme.txt";
|
||||
private const string UPDATE_INSTALL_FILE = "AutoUpdateInstallIDTemplate.txt";
|
||||
|
||||
private const string UPDATEURL_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_URLS";
|
||||
|
||||
internal const string UPDATEURL_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_URLS";
|
||||
|
||||
static AutoUpdateSettings()
|
||||
{
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7E119745-1F62-43F0-936C-F312A1912C0B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Duplicati.Library.AutoUpdater</RootNamespace>
|
||||
<AssemblyName>Duplicati.Library.AutoUpdater</AssemblyName>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>..\..\GUI\Duplicati.GUI.TrayIcon\Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
<StartupObject>Duplicati.Library.AutoUpdater.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -43,6 +44,7 @@
|
||||
<Compile Include="FileEntry.cs" />
|
||||
<Compile Include="SignatureReadingStream.cs" />
|
||||
<Compile Include="AutoUpdateSettings.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2014, Kenneth Skovhede
|
||||
|
||||
// http://www.hexad.dk, opensource@hexad.dk
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Duplicati.Library.AutoUpdater
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args, AutoUpdateStrategy.Never);
|
||||
}
|
||||
|
||||
public static int RealMain(string[] _args)
|
||||
{
|
||||
var args = new List<string>(_args);
|
||||
Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
|
||||
|
||||
if (args.Count == 0)
|
||||
{
|
||||
WriteUsage();
|
||||
return 100;
|
||||
}
|
||||
else if (args.Count != 1)
|
||||
{
|
||||
Console.WriteLine("Invalid number of arguments, got {0}:{1}{1}{2}{1}{1}", args.Count, Environment.NewLine, string.Join(Environment.NewLine, args));
|
||||
return 100;
|
||||
}
|
||||
|
||||
var cmd = args[0].ToLowerInvariant().Trim();
|
||||
switch (cmd)
|
||||
{
|
||||
case "help":
|
||||
WriteUsage();
|
||||
return 0;
|
||||
case "list":
|
||||
{
|
||||
var versions = UpdaterManager.FindInstalledVersions();
|
||||
var selfdir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||||
if (string.Equals(Library.Utility.Utility.AppendDirSeparator(selfdir), Library.Utility.Utility.AppendDirSeparator(UpdaterManager.InstalledBaseDir)))
|
||||
versions = versions.Union(new KeyValuePair<string, UpdateInfo>[] { new KeyValuePair<string, UpdateInfo>(selfdir, UpdaterManager.SelfVersion) });
|
||||
Console.WriteLine(string.Join(Environment.NewLine, versions.Select(x => string.Format(" {0} {1} ({2})", (x.Value.Version == UpdaterManager.SelfVersion.Version ? "*" : "-"), x.Value.Displayname, x.Value.Version))));
|
||||
return 0;
|
||||
}
|
||||
case "check":
|
||||
{
|
||||
var update = UpdaterManager.CheckForUpdate();
|
||||
if (update == null)
|
||||
Console.WriteLine("No updates found");
|
||||
else if (update.Version == UpdaterManager.SelfVersion.Version)
|
||||
Console.WriteLine("You are running the latest version: {0}", update.Displayname);
|
||||
else
|
||||
Console.WriteLine("New version is available: {0}", update.Displayname);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case "install":
|
||||
{
|
||||
var update = UpdaterManager.CheckForUpdate();
|
||||
if (update == null || update.Version == UpdaterManager.SelfVersion.Version)
|
||||
{
|
||||
Console.WriteLine("You are running the latest version: {0} ({1})", UpdaterManager.SelfVersion.Displayname, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
|
||||
return 0;
|
||||
}
|
||||
Console.WriteLine("Downloading update \"{0}\" ...", update.Displayname);
|
||||
|
||||
long lastpg = 0;
|
||||
UpdaterManager.DownloadAndUnpackUpdate(update, f => {
|
||||
var npg = (long)(f*100);
|
||||
if (Math.Abs(npg - lastpg) >= 5 || (npg == 100 && lastpg != 100))
|
||||
{
|
||||
lastpg = npg;
|
||||
Console.WriteLine("Downloading {0}% ...", npg);
|
||||
}
|
||||
});
|
||||
|
||||
Console.WriteLine("New version \"{0}\" installed!", update.Displayname);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
Console.WriteLine("Unknown command: \"{0}\"", args[0]);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Try the command \"{0}\" instead", "help");
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteUsage()
|
||||
{
|
||||
Console.WriteLine("Usage:{0}\t{1}{2} [LIST|CHECK|INSTALL|HELP]", Environment.NewLine, Duplicati.Library.Utility.Utility.IsMono ? "mono " : "", System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location));
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Environment variables:");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("{0} - Disables updates completely", string.Format(UpdaterManager.SKIPUPDATE_ENVNAME_TEMPLATE, AutoUpdateSettings.AppName));
|
||||
Console.WriteLine("{0} - Choose how to handle updates, valid settings: {1}", string.Format(UpdaterManager.UPDATE_STRATEGY_ENVNAME_TEMPLATE, AutoUpdateSettings.AppName), string.Join(", ", Enum.GetNames(typeof(AutoUpdateStrategy))));
|
||||
Console.WriteLine("{0} - Use alternate updates urls", string.Format(AutoUpdateSettings.UPDATEURL_ENVNAME_TEMPLATE, AutoUpdateSettings.AppName));
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Updates are downloaded from: {0}", string.Join(";", AutoUpdateSettings.URLs));
|
||||
Console.WriteLine("Updates are installed in: {0}", UpdaterManager.INSTALLDIR);
|
||||
Console.WriteLine("The base install dir is: {0}", UpdaterManager.InstalledBaseDir);
|
||||
Console.WriteLine("This version is \"{0}\" ({1}) and is installed in: {2}", UpdaterManager.SelfVersion.Displayname, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version, System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Duplicati.Library.AutoUpdater
|
||||
private static readonly string[] MANIFEST_URLS = AutoUpdateSettings.URLs;
|
||||
private static readonly string APPNAME = AutoUpdateSettings.AppName;
|
||||
|
||||
private static readonly string INSTALLDIR;
|
||||
internal static readonly string INSTALLDIR;
|
||||
|
||||
private static readonly string INSTALLED_BASE_DIR = string.IsNullOrWhiteSpace(System.Environment.GetEnvironmentVariable(string.Format(INSTALLDIR_ENVNAME_TEMPLATE, APPNAME))) ?
|
||||
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location)
|
||||
@@ -50,16 +50,16 @@ namespace Duplicati.Library.AutoUpdater
|
||||
|
||||
private static KeyValuePair<string, UpdateInfo>? m_hasUpdateInstalled;
|
||||
|
||||
private static readonly UpdateInfo SelfVersion;
|
||||
public static readonly UpdateInfo SelfVersion;
|
||||
|
||||
public static event Action<Exception> OnError;
|
||||
|
||||
private const string DATETIME_FORMAT = "yyyymmddhhMMss";
|
||||
private const string INSTALLDIR_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_INSTALL_ROOT";
|
||||
private const string SKIPUPDATE_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_SKIP_UPDATE";
|
||||
internal const string SKIPUPDATE_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_SKIP_UPDATE";
|
||||
private const string RUN_UPDATED_FOLDER_PATH = "AUTOUPDATER_LOAD_UPDATE";
|
||||
private const string SLEEP_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_SLEEP";
|
||||
private const string UPDATE_STRATEGY_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_POLICY";
|
||||
internal const string UPDATE_STRATEGY_ENVNAME_TEMPLATE = "AUTOUPDATER_{0}_POLICY";
|
||||
private const string UPDATE_MANIFEST_FILENAME = "autoupdate.manifest";
|
||||
private const string README_FILE = "README.txt";
|
||||
private const string INSTALL_FILE = "installation.txt";
|
||||
@@ -71,6 +71,11 @@ namespace Duplicati.Library.AutoUpdater
|
||||
/// <value>The original directory that this application was installed into</value>
|
||||
public static string InstalledBaseDir { get { return INSTALLED_BASE_DIR; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last version found from an update
|
||||
/// </summary>
|
||||
public static UpdateInfo LastUpdateCheckVersion { get; private set; }
|
||||
|
||||
static UpdaterManager()
|
||||
{
|
||||
string installdir = null;
|
||||
@@ -197,7 +202,7 @@ namespace Duplicati.Library.AutoUpdater
|
||||
using(var tmpfile = new Library.Utility.TempFile())
|
||||
{
|
||||
System.Net.WebClient wc = new System.Net.WebClient();
|
||||
wc.Headers.Add(System.Net.HttpRequestHeader.UserAgent, string.Format("{0} v{1}", APPNAME, SelfVersion.Version));
|
||||
wc.Headers.Add(System.Net.HttpRequestHeader.UserAgent, string.Format("{0} v{1}{2}", APPNAME, SelfVersion.Version, string.IsNullOrWhiteSpace(InstallID) ? "" : " -" + InstallID));
|
||||
wc.Headers.Add("X-Install-ID", InstallID);
|
||||
wc.DownloadFile(url, tmpfile);
|
||||
|
||||
@@ -214,6 +219,7 @@ namespace Duplicati.Library.AutoUpdater
|
||||
if (string.Equals(SelfVersion.ReleaseType, "Debug", StringComparison.InvariantCultureIgnoreCase) && !string.Equals(update.ReleaseType, SelfVersion.ReleaseType, StringComparison.CurrentCultureIgnoreCase))
|
||||
return null;
|
||||
|
||||
LastUpdateCheckVersion = update;
|
||||
return update;
|
||||
}
|
||||
}
|
||||
@@ -856,7 +862,7 @@ namespace Duplicati.Library.AutoUpdater
|
||||
}
|
||||
}
|
||||
|
||||
public static int RunFromMostRecent(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.InstallDuring)
|
||||
public static int RunFromMostRecent(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
|
||||
{
|
||||
// If the update is disabled, go straight in
|
||||
if (DISABLE_UPDATE_DOMAIN)
|
||||
|
||||
@@ -226,10 +226,6 @@
|
||||
<Project>{2C838169-B187-4B09-8768-1C24C2521C8D}</Project>
|
||||
<Name>Duplicati.Library.SQLiteHelper</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
|
||||
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
|
||||
<Name>Duplicati.Library.AutoUpdater</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
|
||||
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
|
||||
<Name>Duplicati.Library.Backend.OneDrive</Name>
|
||||
@@ -242,6 +238,10 @@
|
||||
<Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
|
||||
<Name>Duplicati.Library.Localization</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
|
||||
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
|
||||
<Name>Duplicati.Library.AutoUpdater</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Strings\DuplicatiRunner.resx">
|
||||
|
||||
@@ -42,5 +42,9 @@
|
||||
<Project>{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}</Project>
|
||||
<Name>Duplicati.Server</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Library\AutoUpdater\Duplicati.Library.AutoUpdater.csproj">
|
||||
<Project>{7E119745-1F62-43F0-936C-F312A1912C0B}</Project>
|
||||
<Name>Duplicati.Library.AutoUpdater</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user