diff --git a/Duplicati/Server/webroot/ngax/templates/notificationarea.html b/Duplicati/Server/webroot/ngax/templates/notificationarea.html
index 852dbbef3..e91cb6bd9 100644
--- a/Duplicati/Server/webroot/ngax/templates/notificationarea.html
+++ b/Duplicati/Server/webroot/ngax/templates/notificationarea.html
@@ -19,16 +19,13 @@
-
New update found: {{message}}
+
diff --git a/Duplicati/Server/webroot/ngax/templates/updatechangelog.html b/Duplicati/Server/webroot/ngax/templates/updatechangelog.html
index ee5755dfe..881d5b25e 100644
--- a/Duplicati/Server/webroot/ngax/templates/updatechangelog.html
+++ b/Duplicati/Server/webroot/ngax/templates/updatechangelog.html
@@ -7,8 +7,7 @@
Loading …
diff --git a/Duplicati/Service/Program.cs b/Duplicati/Service/Program.cs
index e01500692..25a6d5006 100644
--- a/Duplicati/Service/Program.cs
+++ b/Duplicati/Service/Program.cs
@@ -1,4 +1,4 @@
-// Copyright (C) 2024, The Duplicati Team
+// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -27,15 +27,11 @@ namespace Duplicati.Service
{
[STAThread]
public static int Main(string[] args)
- {
- return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args, Duplicati.Library.AutoUpdater.AutoUpdateStrategy.Never);
- }
-
- public static void RealMain(string[] args)
{
using(var runner = new Runner(args))
runner.Wait();
+ return 0;
}
}
}
diff --git a/Duplicati/UnitTest/BackendToolTests.cs b/Duplicati/UnitTest/BackendToolTests.cs
index 1ec94df54..2b3c4b631 100755
--- a/Duplicati/UnitTest/BackendToolTests.cs
+++ b/Duplicati/UnitTest/BackendToolTests.cs
@@ -66,7 +66,7 @@ namespace Duplicati.UnitTest
{
// Absolute path
var downloadFileName = Path.Combine(absoluteDownloadFolder, Path.GetFileName(targetFile));
- var status = CommandLine.BackendTool.Program.RealMain(new[] { "GET", $"{backendURL}", $"{downloadFileName}" });
+ var status = CommandLine.BackendTool.Program.Main(new[] { "GET", $"{backendURL}", $"{downloadFileName}" });
Assert.AreEqual(0, status);
Assert.IsTrue(File.Exists(downloadFileName));
TestUtils.AssertFilesAreEqual(targetFile, downloadFileName, false, downloadFileName);
@@ -83,7 +83,7 @@ namespace Duplicati.UnitTest
{
// Relative path
var downloadFileName = Path.GetFileName(targetFile);
- var status = CommandLine.BackendTool.Program.RealMain(new[] { "GET", $"{backendURL}", $"{downloadFileName}" });
+ var status = CommandLine.BackendTool.Program.Main(new[] { "GET", $"{backendURL}", $"{downloadFileName}" });
Assert.AreEqual(0, status);
Assert.IsTrue(File.Exists(downloadFileName));
TestUtils.AssertFilesAreEqual(targetFile, downloadFileName, false, downloadFileName);
diff --git a/Duplicati/UnitTest/CommandLineOperationsTests.cs b/Duplicati/UnitTest/CommandLineOperationsTests.cs
index 86ec197d4..fa387fc9b 100644
--- a/Duplicati/UnitTest/CommandLineOperationsTests.cs
+++ b/Duplicati/UnitTest/CommandLineOperationsTests.cs
@@ -1,4 +1,4 @@
-// Copyright (C) 2024, The Duplicati Team
+// Copyright (C) 2024, The Duplicati Team
// https://duplicati.com, hello@duplicati.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
@@ -174,17 +174,17 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Running backup with {0} data added ...", Duplicati.Library.Utility.Utility.FormatSizeString(size));
using (new Library.Logging.Timer(LOGTAG, "BackupWithDataAdded", string.Format("Backup with {0} data added", Duplicati.Library.Utility.Utility.FormatSizeString(size))))
- Duplicati.CommandLine.Program.RealMain(backupargs);
+ Duplicati.CommandLine.Program.Main(backupargs);
ProgressWriteLine("Testing data ...");
using (new Library.Logging.Timer(LOGTAG, "TestRemoteData", "Test remote data"))
- if (Duplicati.CommandLine.Program.RealMain((new string[] { "test", target, "all" }.Union(opts)).ToArray()) != 0)
+ if (Duplicati.CommandLine.Program.Main((new string[] { "test", target, "all" }.Union(opts)).ToArray()) != 0)
throw new Exception("Failed during remote verification");
}
ProgressWriteLine("Running unchanged backup ...");
using (new Library.Logging.Timer(LOGTAG, "UnchangedBackup", "Unchanged backup"))
- Duplicati.CommandLine.Program.RealMain(backupargs);
+ Duplicati.CommandLine.Program.Main(backupargs);
var datafolders = systemIO.EnumerateDirectories(DATAFOLDER);
@@ -195,7 +195,7 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Running backup with renamed folder...");
using (new Library.Logging.Timer(LOGTAG, "BackupWithRenamedFolder", "Backup with renamed folder"))
- Duplicati.CommandLine.Program.RealMain(backupargs);
+ Duplicati.CommandLine.Program.Main(backupargs);
datafolders = systemIO.EnumerateDirectories(DATAFOLDER);
@@ -212,11 +212,11 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Running backup with deleted data...");
using (new Library.Logging.Timer(LOGTAG, "BackupWithDeletedData", "Backup with deleted data"))
- Duplicati.CommandLine.Program.RealMain(backupargs);
+ Duplicati.CommandLine.Program.Main(backupargs);
ProgressWriteLine("Testing the compare method ...");
using (new Library.Logging.Timer(LOGTAG, "CompareMethod", "Compare method"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "compare", target, "0", "1" }.Union(opts)).ToArray());
+ Duplicati.CommandLine.Program.Main((new string[] { "compare", target, "0", "1" }.Union(opts)).ToArray());
for (var i = 0; i < 5; i++)
{
@@ -224,12 +224,12 @@ namespace Duplicati.UnitTest
systemIO.FileCopy(LOGFILE, Path.Combine(SOURCEFOLDER, Path.GetFileName(LOGFILE)), true);
using (new Library.Logging.Timer(LOGTAG, "BackupWithLogfileChange", string.Format("Backup with logfilechange {0}", i + 1)))
- Duplicati.CommandLine.Program.RealMain(backupargs);
+ Duplicati.CommandLine.Program.Main(backupargs);
}
ProgressWriteLine("Compacting data ...");
using (new Library.Logging.Timer(LOGTAG, "Compacting", "Compacting"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "compact", target, "--small-file-max-count=2" }.Union(opts)).ToArray());
+ Duplicati.CommandLine.Program.Main((new string[] { "compact", target, "--small-file-max-count=2" }.Union(opts)).ToArray());
datafolders = systemIO.EnumerateDirectories(DATAFOLDER);
@@ -237,7 +237,7 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Partial restore of {0} ...", Path.GetFileName(rf));
using (new Library.Logging.Timer(LOGTAG, "PartialRestore", "Partial restore"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "restore", target, rf + "*", "--restore-path=\"" + RESTOREFOLDER + "\"" }.Union(opts)).ToArray());
+ Duplicati.CommandLine.Program.Main((new string[] { "restore", target, rf + "*", "--restore-path=\"" + RESTOREFOLDER + "\"" }.Union(opts)).ToArray());
ProgressWriteLine("Verifying partial restore ...");
using (new Library.Logging.Timer(LOGTAG, "VerificationOfPartialRestore", "Verification of partial restored files"))
@@ -247,7 +247,7 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Partial restore of {0} without local db...", Path.GetFileName(rf));
using (new Library.Logging.Timer(LOGTAG, "PartialRestoreWithoutLocalDb", "Partial restore without local db"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "restore", target, rf + "*", "--restore-path=\"" + RESTOREFOLDER + "\"", "--no-local-db" }.Union(opts)).ToArray());
+ Duplicati.CommandLine.Program.Main((new string[] { "restore", target, rf + "*", "--restore-path=\"" + RESTOREFOLDER + "\"", "--no-local-db" }.Union(opts)).ToArray());
ProgressWriteLine("Verifying partial restore ...");
using (new Library.Logging.Timer(LOGTAG, "VerificationOfPartialRestore", "Verification of partial restored files"))
@@ -257,7 +257,7 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Full restore ...");
using (new Library.Logging.Timer(LOGTAG, "FullRestore", "Full restore"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "restore", target, "*", "--restore-path=\"" + RESTOREFOLDER + "\"" }.Union(opts)).ToArray());
+ Duplicati.CommandLine.Program.Main((new string[] { "restore", target, "*", "--restore-path=\"" + RESTOREFOLDER + "\"" }.Union(opts)).ToArray());
ProgressWriteLine("Verifying full restore ...");
using (new Library.Logging.Timer(LOGTAG, "VerificationOfFullRestore", "Verification of restored files"))
@@ -268,7 +268,7 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Full restore without local db...");
using (new Library.Logging.Timer(LOGTAG, "FullRestoreWithoutDb", "Full restore without local db"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "restore", target, "*", "--restore-path=\"" + RESTOREFOLDER + "\"", "--no-local-db" }.Union(opts)).ToArray());
+ Duplicati.CommandLine.Program.Main((new string[] { "restore", target, "*", "--restore-path=\"" + RESTOREFOLDER + "\"", "--no-local-db" }.Union(opts)).ToArray());
ProgressWriteLine("Verifying full restore ...");
using (new Library.Logging.Timer(LOGTAG, "VerificationOfFullRestoreWithoutDb", "Verification of restored files"))
@@ -277,7 +277,7 @@ namespace Duplicati.UnitTest
ProgressWriteLine("Testing data ...");
using (new Library.Logging.Timer(LOGTAG, "TestRemoteData", "Test remote data"))
- if (Duplicati.CommandLine.Program.RealMain((new string[] { "test", target, "all" }.Union(opts)).ToArray()) != 0)
+ if (Duplicati.CommandLine.Program.Main((new string[] { "test", target, "all" }.Union(opts)).ToArray()) != 0)
throw new Exception("Failed during final remote verification");
}
}
diff --git a/Duplicati/UnitTest/RecoveryToolTests.cs b/Duplicati/UnitTest/RecoveryToolTests.cs
index f654bbb77..80f9dc1af 100644
--- a/Duplicati/UnitTest/RecoveryToolTests.cs
+++ b/Duplicati/UnitTest/RecoveryToolTests.cs
@@ -90,17 +90,17 @@ namespace Duplicati.UnitTest
// Download the backend files.
string downloadFolder = Path.Combine(this.RESTOREFOLDER, "downloadedFiles");
Directory.CreateDirectory(downloadFolder);
- int status = CommandLine.RecoveryTool.Program.RealMain(new[] {"download", $"{backendURL}", $"{downloadFolder}", $"--passphrase={options["passphrase"]}"});
+ int status = CommandLine.RecoveryTool.Program.Main(new[] {"download", $"{backendURL}", $"{downloadFolder}", $"--passphrase={options["passphrase"]}"});
Assert.AreEqual(0, status);
// Create the index.
- status = CommandLine.RecoveryTool.Program.RealMain(new[] {"index", $"{downloadFolder}", $"--build-index-with-files={buildIndexWithFiles}"});
+ status = CommandLine.RecoveryTool.Program.Main(new[] {"index", $"{downloadFolder}", $"--build-index-with-files={buildIndexWithFiles}"});
Assert.AreEqual(0, status);
// Restore to a different folder.
string restoreFolder = Path.Combine(this.RESTOREFOLDER, "restoredFiles");
Directory.CreateDirectory(restoreFolder);
- status = CommandLine.RecoveryTool.Program.RealMain(new[] {"restore", $"{downloadFolder}", $"--targetpath={restoreFolder}"});
+ status = CommandLine.RecoveryTool.Program.Main(new[] {"restore", $"{downloadFolder}", $"--targetpath={restoreFolder}"});
Assert.AreEqual(0, status);
// Since this.DATAFOLDER is a folder, Path.GetFileName will return the name of the
diff --git a/Duplicati/WebserverCore/DuplicatiWebserver.cs b/Duplicati/WebserverCore/DuplicatiWebserver.cs
index ca227d420..42935a639 100644
--- a/Duplicati/WebserverCore/DuplicatiWebserver.cs
+++ b/Duplicati/WebserverCore/DuplicatiWebserver.cs
@@ -18,8 +18,8 @@ namespace Duplicati.WebserverCore
app.UseAuthMiddleware();
- string webroot = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
- string install_webroot = System.IO.Path.Combine(Library.AutoUpdater.UpdaterManager.InstalledBaseDir, "webroot");
+ string webroot = System.IO.Path.GetDirectoryName(Duplicati.Library.Utility.Utility.getEntryAssembly().Location);
+ string install_webroot = System.IO.Path.Combine(Library.AutoUpdater.UpdaterManager.INSTALLATIONDIR, "webroot");
webroot = System.IO.Path.Combine(webroot, "webroot");
var webroot_fileprovider = new PhysicalFileProvider(webroot);
diff --git a/Duplicati/WindowsService/Program.cs b/Duplicati/WindowsService/Program.cs
index d0d425c1a..deb3f9d2c 100644
--- a/Duplicati/WindowsService/Program.cs
+++ b/Duplicati/WindowsService/Program.cs
@@ -1,32 +1,27 @@
-// Copyright (C) 2024, The Duplicati Team
-// https://duplicati.com, hello@duplicati.com
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
+// Copyright (C) 2024, The Duplicati Team
+// https://duplicati.com, hello@duplicati.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Reflection;
-using System.Security.Principal;
using System.ServiceProcess;
-using System.Text;
-using System.Threading.Tasks;
namespace Duplicati.WindowsService
{
@@ -34,11 +29,6 @@ namespace Duplicati.WindowsService
{
[STAThread]
public static int Main(string[] args)
- {
- return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args, Duplicati.Library.AutoUpdater.AutoUpdateStrategy.Never);
- }
-
- public static void RealMain(string[] args)
{
var install = args != null && args.Any(x => string.Equals("install", x, StringComparison.OrdinalIgnoreCase));
var uninstall = args != null && args.Any(x => string.Equals("uninstall", x, StringComparison.OrdinalIgnoreCase));
@@ -79,6 +69,7 @@ namespace Duplicati.WindowsService
catch (Exception ex)
{
Console.WriteLine("Duplicati service delete failed. Exception: {0}", ex.Message);
+ return 1;
}
}
if (install)
@@ -93,6 +84,7 @@ namespace Duplicati.WindowsService
catch (Exception ex)
{
Console.WriteLine("Duplicati service installation failed. Exception: {0}", ex.Message);
+ return 1;
}
}
}
@@ -100,6 +92,8 @@ namespace Duplicati.WindowsService
{
ServiceBase.Run(new ServiceBase[] { new ServiceControl(args) });
}
+
+ return 0;
}
}
}