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/GUI/Duplicati.GUI.TrayIcon/Program.cs')
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs231
1 files changed, 152 insertions, 79 deletions
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
index 883a1c868..79324e237 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
@@ -1,7 +1,7 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System.Windows.Forms;
+using System.Net;
using Duplicati.Library.Interface;
namespace Duplicati.GUI.TrayIcon
@@ -19,22 +19,24 @@ namespace Duplicati.GUI.TrayIcon
private const string HOSTURL_OPTION = "hosturl";
private const string NOHOSTEDSERVER_OPTION = "no-hosted-server";
-
+ private const string READCONFIGFROMDB_OPTION = "read-config-from-db";
+
+ private const string DETACHED_PROCESS = "detached-process";
private const string BROWSER_COMMAND_OPTION = "browser-command";
- private const string DEFAULT_HOSTURL = "http://localhost:8080";
+ private const string DEFAULT_HOSTURL = "http://localhost:8200";
private static string _browser_command = null;
public static string BrowserCommand { get { return _browser_command; } }
-
-
+ public static Server.Database.Connection databaseConnection = null;
+
private static string GetDefaultToolKit(bool printwarnings)
{
// No longer using Cocoa directly as it fails on 32bit as well
if (Duplicati.Library.Utility.Utility.IsClientOSX)
return TOOLKIT_RUMPS;
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
if (Duplicati.Library.Utility.Utility.IsClientLinux)
{
if (SupportsAppIndicator)
@@ -65,12 +67,15 @@ namespace Duplicati.GUI.TrayIcon
List<string> args = new List<string>(_args);
Dictionary<string, string> options = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
+ if (Duplicati.Library.Utility.Utility.IsClientWindows && (Duplicati.Library.AutoUpdater.UpdaterManager.IsRunningInUpdateEnvironment || !Duplicati.Library.Utility.Utility.ParseBoolOption(options, DETACHED_PROCESS)))
+ Duplicati.Library.Utility.Win32.AttachConsole(Duplicati.Library.Utility.Win32.ATTACH_PARENT_PROCESS);
+
foreach (string s in args)
if (
- s.Equals("help", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("/help", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("usage", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("/usage", StringComparison.InvariantCultureIgnoreCase))
+ s.Equals("help", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("/help", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("usage", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("/usage", StringComparison.OrdinalIgnoreCase))
options["help"] = "";
if (options.ContainsKey("help"))
@@ -79,7 +84,11 @@ namespace Duplicati.GUI.TrayIcon
Console.WriteLine();
foreach (Library.Interface.ICommandLineArgument arg in SupportedCommands)
+ {
Console.WriteLine("--{0}: {1}", arg.Name, arg.LongDescription);
+ if (arg.Name == TOOLKIT_OPTION)
+ Console.WriteLine(" Supported toolkits: {0}{1}", string.Join(", ", arg.ValidValues), Environment.NewLine);
+ }
Console.WriteLine("Additionally, these server options are also supported:");
Console.WriteLine();
@@ -88,35 +97,43 @@ namespace Duplicati.GUI.TrayIcon
Console.WriteLine("--{0}: {1}", arg.Name, arg.LongDescription);
return;
- }
-
+ }
+
options.TryGetValue(BROWSER_COMMAND_OPTION, out _browser_command);
string toolkit;
if (!options.TryGetValue(TOOLKIT_OPTION, out toolkit))
+ {
+#if !(__MonoCS__ || __WindowsGTK__ || ENABLE_GTK)
+ if (Library.Utility.Utility.IsClientLinux && !Library.Utility.Utility.IsClientOSX)
+ Console.WriteLine("Warning: this build does not support GTK, rebuild with ENABLE_GTK defined");
+#endif
toolkit = GetDefaultToolKit(true);
+ }
else
{
- if (TOOLKIT_WINDOWS_FORMS.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ if (TOOLKIT_WINDOWS_FORMS.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_WINDOWS_FORMS;
-#if __MonoCS__ || __WindowsGTK__
- else if (TOOLKIT_GTK.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
+ else if (TOOLKIT_GTK.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_GTK;
- else if (TOOLKIT_GTK_APP_INDICATOR.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ else if (TOOLKIT_GTK_APP_INDICATOR.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_GTK_APP_INDICATOR;
#endif
- else if (TOOLKIT_COCOA.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ else if (TOOLKIT_COCOA.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_COCOA;
- else if (TOOLKIT_RUMPS.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ else if (TOOLKIT_RUMPS.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_RUMPS;
else
toolkit = GetDefaultToolKit(true);
}
HostedInstanceKeeper hosted = null;
- bool openui = false;
+ var openui = false;
string password = null;
- bool saltedpassword = false;
+ var saltedpassword = false;
+ var serverURL = new Uri(DEFAULT_HOSTURL);
+
if (!Library.Utility.Utility.ParseBoolOption(options, NOHOSTEDSERVER_OPTION))
{
try
@@ -133,78 +150,126 @@ namespace Duplicati.GUI.TrayIcon
openui = Duplicati.Server.Program.IsFirstRun || Duplicati.Server.Program.ServerPortChanged;
password = Duplicati.Server.Program.DataConnection.ApplicationSettings.WebserverPassword;
saltedpassword = true;
+ serverURL = (new UriBuilder(serverURL) { Port = Duplicati.Server.Program.ServerPort }).Uri;
}
+
+ if (Library.Utility.Utility.ParseBoolOption(options, NOHOSTEDSERVER_OPTION) && Library.Utility.Utility.ParseBoolOption(options, READCONFIGFROMDB_OPTION))
+ databaseConnection = Server.Program.GetDatabaseConnection(options);
- using (hosted)
+ string pwd;
+
+ if (options.TryGetValue("webserver-password", out pwd))
{
- string url;
- if (!options.TryGetValue(HOSTURL_OPTION, out url))
- {
- if (hosted == null)
- {
- url = DEFAULT_HOSTURL;
- }
- else
+ password = pwd;
+ saltedpassword = false;
+ }
+
+ if (databaseConnection != null)
+ {
+ password = databaseConnection.ApplicationSettings.WebserverPasswordTrayIcon;
+ saltedpassword = false;
+ }
+
+ if (databaseConnection != null)
+ {
+ var cert = databaseConnection.ApplicationSettings.ServerSSLCertificate;
+ var scheme = "http";
+
+ if (cert != null && cert.HasPrivateKey)
+ scheme = "https";
+
+ serverURL = (new UriBuilder(serverURL)
{
- int port = Duplicati.Server.Program.ServerPort;
- url = "http://127.0.0.1:" + port;
- }
- }
+ Port = databaseConnection.ApplicationSettings.LastWebserverPort == -1 ? serverURL.Port : databaseConnection.ApplicationSettings.LastWebserverPort,
+ Scheme = scheme
+ }).Uri;
+ }
- string pwd;
- if (options.TryGetValue("webserver-password", out pwd))
- {
- password = pwd;
- saltedpassword = false;
- }
+ string url;
+
+ if (options.TryGetValue(HOSTURL_OPTION, out url))
+ serverURL = new Uri(url);
+
+ using (hosted)
+ {
+ var reSpawn = 0;
- using (Connection = new HttpServerConnection(new Uri(url), password, saltedpassword))
+ do
{
- using(var tk = RunTrayIcon(toolkit))
+ try
{
- if (hosted != null && Server.Program.Instance != null)
- Server.Program.Instance.SecondInstanceDetected += new Server.SingleInstance.SecondInstanceDelegate(x => { tk.ShowUrlInWindow(url); });
-
- // TODO: If we change to hosted browser this should be a callback
- if (openui)
- {
- try
- {
- tk.ShowUrlInWindow(Connection.StatusWindowURL);
+ System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
- Duplicati.Server.Program.IsFirstRun = false;
- Duplicati.Server.Program.ServerPortChanged = false;
- }
- catch
+ using (Connection = new HttpServerConnection(serverURL, password, saltedpassword, databaseConnection != null, options))
+ {
+ using (var tk = RunTrayIcon(toolkit))
{
+ if (hosted != null && Server.Program.Instance != null)
+ Server.Program.Instance.SecondInstanceDetected +=
+ new Server.SingleInstance.SecondInstanceDelegate(
+ x => { tk.ShowUrlInWindow(serverURL.ToString()); });
+
+ // TODO: If we change to hosted browser this should be a callback
+ if (openui)
+ {
+ try
+ {
+ tk.ShowUrlInWindow(Connection.StatusWindowURL);
+
+ Duplicati.Server.Program.IsFirstRun = false;
+ Duplicati.Server.Program.ServerPortChanged = false;
+ }
+ catch
+ {
+ }
+ }
+
+ // If the server shuts down, shut down the tray-icon as well
+ Action shutdownEvent = () =>
+ {
+ // Make sure we do not start again after
+ // a controlled exit
+ reSpawn = 100;
+ tk.InvokeExit();
+ };
+
+ if (hosted != null)
+ hosted.InstanceShutdown += shutdownEvent;
+
+ tk.Init(_args);
+
+ // If the tray-icon quits, stop the server
+ reSpawn = 100;
+
+ // Make sure that the server shutdown does not access the tray-icon,
+ // as it would be disposed by now
+ if (hosted != null)
+ hosted.InstanceShutdown -= shutdownEvent;
}
}
+ }
+ catch (WebException ex)
+ {
+ System.Diagnostics.Trace.WriteLine("Request error: " + ex.ToString());
+ Console.WriteLine("Request error: " + ex.ToString());
- // If the server shuts down, shut down the tray-icon as well
- Action shutdownEvent = () =>
- {
- tk.InvokeExit();
- };
-
- if (hosted != null)
- hosted.InstanceShutdown += shutdownEvent;
-
- tk.Init(_args);
-
- // Make sure that the server shutdown does not access the tray-icon,
- // as it would be disposed by now
- if (hosted != null)
- hosted.InstanceShutdown -= shutdownEvent;
+ reSpawn++;
}
- }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine("Unexpected error: " + ex.ToString());
+ Console.WriteLine("Unexpected error: " + ex.ToString());
+ return;
+ }
+ } while (reSpawn < 3);
}
}
-
+
private static TrayIconBase RunTrayIcon(string toolkit)
{
if (toolkit == TOOLKIT_WINDOWS_FORMS)
return GetWinformsInstance();
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
else if (toolkit == TOOLKIT_GTK)
return GetGtkInstance();
else if (toolkit == TOOLKIT_GTK_APP_INDICATOR)
@@ -215,7 +280,7 @@ namespace Duplicati.GUI.TrayIcon
else if (toolkit == TOOLKIT_RUMPS)
return GetRumpsRunnerInstance();
else
- throw new Exception(string.Format("The selected toolkit '{0}' is invalid", toolkit));
+ throw new UserInformationException(string.Format("The selected toolkit '{0}' is invalid", toolkit));
}
//We keep these in functions to avoid attempting to load the instance,
@@ -227,7 +292,7 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static TrayIconBase GetWinformsInstance() { return new Windows.WinFormsRunner(); }
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static TrayIconBase GetGtkInstance() { return new GtkRunner(); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
@@ -247,7 +312,7 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetGtk()
{
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
return typeof(Gtk.StatusIcon) != null && typeof(Gdk.Image) != null;
#else
return false;
@@ -263,7 +328,7 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetAppIndicator()
{
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
return typeof(AppIndicator.ApplicationIndicator) != null;
#else
return false;
@@ -351,13 +416,21 @@ namespace Duplicati.GUI.TrayIcon
if (SupportsRumps)
toolkits.Add(TOOLKIT_RUMPS);
- return new Duplicati.Library.Interface.ICommandLineArgument[]
+ var args = new List<Duplicati.Library.Interface.ICommandLineArgument>()
{
new Duplicati.Library.Interface.CommandLineArgument(TOOLKIT_OPTION, CommandLineArgument.ArgumentType.Enumeration, "Selects the toolkit to use", "Choose the toolkit used to generate the TrayIcon, note that it will fail if the selected toolkit is not supported on this machine", GetDefaultToolKit(false), null, toolkits.ToArray()),
new Duplicati.Library.Interface.CommandLineArgument(HOSTURL_OPTION, CommandLineArgument.ArgumentType.String, "Selects the url to connect to", "Supply the url that the TrayIcon will connect to and show status for", DEFAULT_HOSTURL),
new Duplicati.Library.Interface.CommandLineArgument(NOHOSTEDSERVER_OPTION, CommandLineArgument.ArgumentType.String, "Disables local server", "Set this option to not spawn a local service, use if the TrayIcon should connect to a running service"),
- new Duplicati.Library.Interface.CommandLineArgument(BROWSER_COMMAND_OPTION, CommandLineArgument.ArgumentType.String, "Sets the browser comand", "Set this option to override the default browser detection"),
+ new Duplicati.Library.Interface.CommandLineArgument(READCONFIGFROMDB_OPTION, CommandLineArgument.ArgumentType.String, "Read server connection info from DB", $"Set this option to read server connection info for running service from its database (only together with {NOHOSTEDSERVER_OPTION})"),
+ new Duplicati.Library.Interface.CommandLineArgument(BROWSER_COMMAND_OPTION, CommandLineArgument.ArgumentType.String, "Sets the browser command", "Set this option to override the default browser detection"),
};
+
+ if (Duplicati.Library.Utility.Utility.IsClientWindows)
+ {
+ args.Add(new Duplicati.Library.Interface.CommandLineArgument(DETACHED_PROCESS, CommandLineArgument.ArgumentType.String, "Runs the tray-icon detached", "This option runs the tray-icon in detached mode, meaning that the process will exit immediately and not send output to the console of the caller"));
+ }
+
+ return args.ToArray();
}
}
}