dmdb/core/ImportExportBase.cs

118 lines
5.1 KiB
C#

using System;
using System.Diagnostics;
using System.Threading;
namespace dezentrale.core
{
//! \short Support functionality for import/export processes
//! \brief Provides methods for executing git/mercurial, holds variables
//! used by the subclasses. Makes use of an ILogger instance
//! for program output.
public abstract class ImportExportBase : BackgroundProcess
{
public model.MemberImportExport ImportExportSettings { get; set; } = null; //!< Instance of the MemberImportExport settings from the configuration class
public string MemberDir { get; set; } = null; //!< Directory that holds the application settings
public string InputDir { get; set; } = null; //!< Import working directory
public string OutputDir { get; set; } = null; //!< Export working directory
//! \brief Run the gpg command with a specified passphrase, in batch-mode without user interaction
//! \param args Custom args to be appended to the gpg call
//! \param gpgPassword Passphrase to be used by GPG to encrypt/decrypt stuff
//! \param log Optional logger instance. If ommitted, Console.WriteLine() will be used
//! \return true if the program executed successfully
//! \return false if gpg was not found or there was another error (see log output)
public static bool Gpg(string args, string gpgPassword, ILogger log = null)
{
string argsFull = $"--batch --yes --passphrase \"{gpgPassword}\" {args}";
return RunProcess("gpg", argsFull, ".", log);
}
//! \short Run a background process (executable)
//! \brief Start a process given by command and arguments,
//! wait for it to finish and log the results.
//! \param cmd Command to execute
//! \param args Argument string (arguments are space-separated).
//! \param workingDir Directory to work in for the external program.
//! \param log Optional logger instance. If ommitted, Console.WriteLine() will be used
//! \return true if the program executed successfully
//! \return false if gpg was not found or there was another error (see log output)
//! \note Spaces within arguments that aren't catched by quotes or escaped with
//! backslash will lead to broken argument parsing by the external program
public static bool RunProcess(string cmd, string args, string workingDir = ".", ILogger log = null)
{
try
{
if (log != null)
{
log.LogLine($"Running {cmd}", model.LogEvent.ELogLevel.Info, "RunProcess");
log.LogRaw($"args: {args}");
log.LogRaw($"dir: {workingDir}");
}
else
{
Console.WriteLine($"cmd: {cmd} {args}");
Console.WriteLine($"dir: {workingDir}");
}
Process p = new Process();
p.StartInfo.FileName = cmd;
p.StartInfo.Arguments = args;
p.StartInfo.WorkingDirectory = workingDir;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
string stdout;
string stderr;
bool toReturn;
//For testing the import/export, the versioning can be omitted by using gpgOnly = true.
bool gpgOnly = false;
if (gpgOnly && !cmd.Equals("gpg"))
{
stdout = "std\r\nout";
stderr = "std\r\nerr";
Thread.Sleep(2000);
toReturn = true;
} else
{
p.Start();
stdout = p.StandardOutput.ReadToEnd();
stderr = p.StandardError.ReadToEnd();
p.WaitForExit();
toReturn = p.ExitCode == 0;
}
if (stdout.Length > 0)
{
if (log != null) log.LogRaw(stdout);
else
{
Console.WriteLine("stdout:");
Console.WriteLine(stdout);
Console.WriteLine();
}
}
if (stderr.Length > 0)
{
if (log != null) log.LogRaw(stderr);
else
{
Console.WriteLine("stderr:");
Console.WriteLine(stderr);
Console.WriteLine();
}
}
return toReturn;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
return false;
}
}
}