diff --git a/Duplicati/Library/Modules/Builtin/RunScript.cs b/Duplicati/Library/Modules/Builtin/RunScript.cs
index 02577d47a..27fcf7901 100644
--- a/Duplicati/Library/Modules/Builtin/RunScript.cs
+++ b/Duplicati/Library/Modules/Builtin/RunScript.cs
@@ -55,6 +55,7 @@ namespace Duplicati.Library.Modules.Builtin
private const string FINISH_OPTION = "run-script-after";
private const string REQUIRED_OPTION = "run-script-before-required";
private const string TIMEOUT_OPTION = "run-script-timeout";
+ private const string ENABLE_ARGUMENTS_OPTION = "run-script-with-arguments";
///
/// Option used to set the log level for mail reports
///
@@ -72,6 +73,7 @@ namespace Duplicati.Library.Modules.Builtin
private string m_startScript = null;
private string m_finishScript = null;
private int m_timeout = 0;
+ private bool m_enableArguments = false;
private string m_operationName;
private string m_remoteurl;
@@ -86,7 +88,7 @@ namespace Duplicati.Library.Modules.Builtin
///
/// The log storage
///
- private Utility.FileBackedStringList m_logstorage;
+ private FileBackedStringList m_logstorage;
#region IGenericModule implementation
@@ -95,10 +97,10 @@ namespace Duplicati.Library.Modules.Builtin
commandlineOptions.TryGetValue(STARTUP_OPTION, out m_startScript);
commandlineOptions.TryGetValue(REQUIRED_OPTION, out m_requiredScript);
commandlineOptions.TryGetValue(FINISH_OPTION, out m_finishScript);
+ m_enableArguments = Utility.Utility.ParseBoolOption(commandlineOptions, ENABLE_ARGUMENTS_OPTION);
- string tmpResultFormat;
ResultExportFormat resultFormat;
- if (!commandlineOptions.TryGetValue(RESULT_FORMAT_OPTION, out tmpResultFormat))
+ if (!commandlineOptions.TryGetValue(RESULT_FORMAT_OPTION, out var tmpResultFormat))
{
resultFormat = ResultExportFormat.Duplicati;
}
@@ -109,8 +111,7 @@ namespace Duplicati.Library.Modules.Builtin
resultFormatSerializer = ResultFormatSerializerProvider.GetSerializer(resultFormat);
- string t;
- if (!commandlineOptions.TryGetValue(TIMEOUT_OPTION, out t))
+ if (!commandlineOptions.TryGetValue(TIMEOUT_OPTION, out var t))
t = DEFAULT_TIMEOUT;
m_timeout = (int)Utility.Timeparser.ParseTimeSpan(t).TotalMilliseconds;
@@ -118,7 +119,7 @@ namespace Duplicati.Library.Modules.Builtin
m_options = commandlineOptions;
m_options.TryGetValue(OPTION_LOG_FILTER, out var logfilterstring);
- var filter = Utility.FilterExpression.ParseLogFilter(logfilterstring);
+ var filter = FilterExpression.ParseLogFilter(logfilterstring);
var logLevel = Utility.Utility.ParseEnumOption(m_options, OPTION_LOG_LEVEL, DEFAULT_LOG_LEVEL);
m_logstorage = new FileBackedStringList();
@@ -148,6 +149,7 @@ namespace Duplicati.Library.Modules.Builtin
new CommandLineArgument(STARTUP_OPTION, CommandLineArgument.ArgumentType.Path, Strings.RunScript.StartupoptionShort, Strings.RunScript.StartupoptionLong),
new CommandLineArgument(FINISH_OPTION, CommandLineArgument.ArgumentType.Path, Strings.RunScript.FinishoptionShort, Strings.RunScript.FinishoptionLong),
new CommandLineArgument(REQUIRED_OPTION, CommandLineArgument.ArgumentType.Path, Strings.RunScript.RequiredoptionShort, Strings.RunScript.RequiredoptionLong),
+ new CommandLineArgument(ENABLE_ARGUMENTS_OPTION, CommandLineArgument.ArgumentType.Boolean, Strings.RunScript.EnableArgumentsShort, Strings.RunScript.EnableArgumentsLong),
new CommandLineArgument(RESULT_FORMAT_OPTION,
CommandLineArgument.ArgumentType.Enumeration,
Strings.RunScript.ResultFormatShort,
@@ -169,10 +171,10 @@ namespace Duplicati.Library.Modules.Builtin
public void OnStart(string operationname, ref string remoteurl, ref string[] localpath)
{
if (!string.IsNullOrEmpty(m_requiredScript))
- Execute(m_requiredScript, "BEFORE", operationname, ref remoteurl, ref localpath, m_timeout, true, m_options, null, null);
+ Execute(m_requiredScript, "BEFORE", operationname, ref remoteurl, ref localpath, m_timeout, true, m_enableArguments, m_options, null, null);
if (!string.IsNullOrEmpty(m_startScript))
- Execute(m_startScript, "BEFORE", operationname, ref remoteurl, ref localpath, m_timeout, false, m_options, null, null);
+ Execute(m_startScript, "BEFORE", operationname, ref remoteurl, ref localpath, m_timeout, false, m_enableArguments, m_options, null, null);
// Save options that might be set by a --run-script-before script so that the OnFinish method
// references the same values.
@@ -226,25 +228,28 @@ namespace Duplicati.Library.Modules.Builtin
using (var streamWriter = new StreamWriter(tmpfile))
streamWriter.Write(resultFormatSerializer.Serialize(result, exception, m_logstorage, null));
- Execute(m_finishScript, "AFTER", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_options, tmpfile, level);
+ Execute(m_finishScript, "AFTER", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_enableArguments, m_options, tmpfile, level);
}
}
#endregion
- private static void Execute(string scriptpath, string eventname, string operationname, ref string remoteurl, ref string[] localpath, int timeout, bool requiredScript, IDictionary options, string datafile, ParsedResultType? level)
+ private static void Execute(string scriptpath, string eventname, string operationname, ref string remoteurl, ref string[] localpath, int timeout, bool requiredScript, bool enableArguments, IDictionary options, string datafile, ParsedResultType? level)
{
try
{
- var args = ARGREGEX.Matches(scriptpath);
- var arguments = new List();
- if (args.Any())
+ var arguments = new List() { scriptpath };
+ if (enableArguments)
{
- arguments = args.AsEnumerable().Select(m => m.Groups["value"].Value).ToList();
- scriptpath = arguments[0];
- arguments.RemoveAt(0);
+ var args = ARGREGEX.Matches(scriptpath);
+ if (args.Any())
+ {
+ arguments = args.AsEnumerable().Select(m => m.Groups["value"].Value).ToList();
+ scriptpath = arguments[0];
+ arguments.RemoveAt(0);
+ }
}
- System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(scriptpath, arguments)
+ var psi = new System.Diagnostics.ProcessStartInfo(scriptpath, arguments)
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
CreateNoWindow = true,
diff --git a/Duplicati/Library/Modules/Builtin/Strings.cs b/Duplicati/Library/Modules/Builtin/Strings.cs
index 791ccb135..f895a679f 100644
--- a/Duplicati/Library/Modules/Builtin/Strings.cs
+++ b/Duplicati/Library/Modules/Builtin/Strings.cs
@@ -93,6 +93,8 @@ namespace Duplicati.Library.Modules.Builtin.Strings
public static string StdErrorReport(string script, string message) { return LC.L(@"The script ""{0}"" reported error messages: {1}", script, message); }
public static string TimeoutoptionLong { get { return LC.L(@"Sets the maximum time a script is allowed to execute. If the script has not completed within this time, it will continue to execute but the operation will continue too, and no script output will be processed."); } }
public static string TimeoutoptionShort { get { return LC.L(@"Sets the script timeout"); } }
+ public static string EnableArgumentsShort { get { return LC.L(@"Enable script arguments"); } }
+ public static string EnableArgumentsLong { get { return LC.L(@"This option enables the use of script arguments. If this option is enabled, the script arguments are treated as commandline strings. Use single or double quotes to separate arguments."); } }
}
internal static class SendMail
{
diff --git a/Duplicati/Library/Modules/Builtin/run-script-example.bat b/Duplicati/Library/Modules/Builtin/run-script-example.bat
index 7f879f74c..e858bbc2b 100644
--- a/Duplicati/Library/Modules/Builtin/run-script-example.bat
+++ b/Duplicati/Library/Modules/Builtin/run-script-example.bat
@@ -11,6 +11,7 @@ REM --run-script-before =
REM --run-script-before-required =
REM --run-script-timeout =