Permalink
Browse files

Another step towards better logging

  • Loading branch information...
synhershko committed Jul 13, 2012
1 parent 13ff650 commit 96fe7421235361261cd651f322c39fac03590205
@@ -7,7 +7,7 @@ namespace WinFormsProgressSample
{
public class LengthyTask : UpdateTaskBase
{
- public override bool Prepare(IUpdateSource source)
+ public override void Prepare(IUpdateSource source)
{
for (int i = 0; i < 50; i++)
{
@@ -26,8 +26,6 @@ public override bool Prepare(IUpdateSource source)
Percentage = 100,
StillWorking = false,
});
-
- return true;
}
public override TaskExecutionStatus Execute(bool coldRun)
@@ -49,6 +49,11 @@ public Logger(List<LogItem> logItems)
LogItems = logItems;
}
+ public void Log(string message, params object[] args)
+ {
+ Log(SeverityLevel.Debug, message, args);
+ }
+
public void Log(SeverityLevel severity, string message, params object[] args)
{
LogItems.Add(new LogItem
@@ -5,95 +5,97 @@
namespace NAppUpdate.Framework.Tasks
{
[Serializable]
- [UpdateTaskAlias("fileUpdate")]
- public class FileUpdateTask : UpdateTaskBase
- {
- [NauField("localPath", "The local path of the file to update", true)]
- public string LocalPath { get; set; }
-
- [NauField("updateTo",
- "File name on the remote location; same name as local path will be used if left blank"
- , false)]
- public string UpdateTo { get; set; }
-
- [NauField("sha256-checksum", "SHA-256 checksum to validate the file after download (optional)", false)]
- public string Sha256Checksum { get; set; }
-
- [NauField("hotswap",
- "Default update action is a cold update; check here if a hot file swap should be attempted"
- , false)]
- public bool CanHotSwap { get; set; }
-
- private string destinationFile, backupFile, tempFile;
-
- public override bool Prepare(Sources.IUpdateSource source)
- {
- if (string.IsNullOrEmpty(LocalPath))
- return true; // Errorneous case, but there's nothing to prepare to...
-
- string fileName;
- if (!string.IsNullOrEmpty(UpdateTo))
- fileName = UpdateTo;
- else
- fileName = LocalPath;
-
- tempFile = null;
-
- try
- {
- string tempFileLocal = Path.Combine(UpdateManager.Instance.Config.TempFolder, Guid.NewGuid().ToString());
- if (!source.GetData(fileName, UpdateManager.Instance.BaseUrl,
- OnProgress,
- ref tempFileLocal))
- return false;
-
- tempFile = tempFileLocal;
- }
- catch (Exception ex)
- {
- throw new UpdateProcessFailedException("Couldn't get Data from source", ex);
- }
-
- if (!string.IsNullOrEmpty(Sha256Checksum))
- {
- string checksum = Utils.FileChecksum.GetSHA256Checksum(tempFile);
- if (!checksum.Equals(Sha256Checksum))
- return false;
- }
-
- destinationFile = Path.Combine(Path.GetDirectoryName(UpdateManager.Instance.ApplicationPath), LocalPath);
-
- return tempFile != null;
- }
+ [UpdateTaskAlias("fileUpdate")]
+ public class FileUpdateTask : UpdateTaskBase
+ {
+ [NauField("localPath", "The local path of the file to update", true)]
+ public string LocalPath { get; set; }
+
+ [NauField("updateTo",
+ "File name on the remote location; same name as local path will be used if left blank"
+ , false)]
+ public string UpdateTo { get; set; }
+
+ [NauField("sha256-checksum", "SHA-256 checksum to validate the file after download (optional)", false)]
+ public string Sha256Checksum { get; set; }
+
+ [NauField("hotswap",
+ "Default update action is a cold update; check here if a hot file swap should be attempted"
+ , false)]
+ public bool CanHotSwap { get; set; }
+
+ private string _destinationFile, _backupFile, _tempFile;
+
+ public override void Prepare(Sources.IUpdateSource source)
+ {
+ if (string.IsNullOrEmpty(LocalPath))
+ {
+ UpdateManager.Instance.Logger.Log(Logger.SeverityLevel.Warning, "FileUpdateTask: LocalPath is empty, task is a noop");
+ return; // Errorneous case, but there's nothing to prepare to, and by default we prefer a noop over an error
+ }
+
+ string fileName;
+ if (!string.IsNullOrEmpty(UpdateTo))
+ fileName = UpdateTo;
+ else
+ fileName = LocalPath;
+
+ _tempFile = null;
+
+ string baseUrl = UpdateManager.Instance.BaseUrl;
+ string tempFileLocal = Path.Combine(UpdateManager.Instance.Config.TempFolder, Guid.NewGuid().ToString());
+
+ UpdateManager.Instance.Logger.Log("FileUpdateTask: Downloading {0} with BaseUrl of {1} to {2}", fileName, baseUrl, tempFileLocal);
+
+ if (!source.GetData(fileName, baseUrl, OnProgress, ref tempFileLocal))
+ throw new UpdateProcessFailedException("FileUpdateTask: Failed to get file from source");
+
+ _tempFile = tempFileLocal;
+ if (_tempFile == null)
+ throw new UpdateProcessFailedException("FileUpdateTask: Failed to get file from source");
+
+ if (!string.IsNullOrEmpty(Sha256Checksum))
+ {
+ string checksum = Utils.FileChecksum.GetSHA256Checksum(_tempFile);
+ if (!checksum.Equals(Sha256Checksum))
+ throw new UpdateProcessFailedException(string.Format("FileUpdateTask: Checksums do not match; expected {0} but got {1}", Sha256Checksum, checksum));
+ }
+
+ _destinationFile = Path.Combine(Path.GetDirectoryName(UpdateManager.Instance.ApplicationPath), LocalPath);
+ UpdateManager.Instance.Logger.Log("FileUpdateTask: Prepared successfully; destination file: {0}", _destinationFile);
+ }
public override TaskExecutionStatus Execute(bool coldRun)
{
if (string.IsNullOrEmpty(LocalPath))
- return TaskExecutionStatus.Successful;
+ {
+ UpdateManager.Instance.Logger.Log(Logger.SeverityLevel.Warning, "FileUpdateTask: LocalPath is empty, task is a noop");
+ return TaskExecutionStatus.Successful; // Errorneous case, but there's nothing to prepare to, and by default we prefer a noop over an error
+ }
- var dirName = Path.GetDirectoryName(destinationFile);
+ var dirName = Path.GetDirectoryName(_destinationFile);
if (!Directory.Exists(dirName))
Utils.FileSystem.CreateDirectoryStructure(dirName, false);
// Create a backup copy if target exists
- if (backupFile == null && File.Exists(destinationFile))
+ if (_backupFile == null && File.Exists(_destinationFile))
{
if (!Directory.Exists(Path.GetDirectoryName(Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath))))
Utils.FileSystem.CreateDirectoryStructure(
Path.GetDirectoryName(Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath)), false);
- backupFile = Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath);
- File.Copy(destinationFile, backupFile, true);
+ _backupFile = Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath);
+ File.Copy(_destinationFile, _backupFile, true);
}
// Only allow execution if the apply attribute was set to hot-swap, or if this is a cold run
if (CanHotSwap || coldRun)
{
try
{
- if (File.Exists(destinationFile))
- File.Delete(destinationFile);
- File.Move(tempFile, destinationFile);
- tempFile = null;
+ if (File.Exists(_destinationFile))
+ File.Delete(_destinationFile);
+ File.Move(_tempFile, _destinationFile);
+ _tempFile = null;
}
catch (Exception ex)
{
@@ -113,24 +115,24 @@ public override TaskExecutionStatus Execute(bool coldRun)
return TaskExecutionStatus.Successful;
// Otherwise, figure out what restart method to use
- if (File.Exists(destinationFile) && !Utils.PermissionsCheck.HaveWritePermissionsForFileOrFolder(destinationFile))
+ if (File.Exists(_destinationFile) && !Utils.PermissionsCheck.HaveWritePermissionsForFileOrFolder(_destinationFile))
{
return TaskExecutionStatus.RequiresPrivilegedAppRestart;
}
return TaskExecutionStatus.RequiresAppRestart;
}
- public override bool Rollback()
- {
- if (string.IsNullOrEmpty(destinationFile))
- return true;
+ public override bool Rollback()
+ {
+ if (string.IsNullOrEmpty(_destinationFile))
+ return true;
- // Copy the backup copy back to its original position
- if (File.Exists(destinationFile))
- File.Delete(destinationFile);
- File.Copy(backupFile, destinationFile, true);
+ // Copy the backup copy back to its original position
+ if (File.Exists(_destinationFile))
+ File.Delete(_destinationFile);
+ File.Copy(_backupFile, _destinationFile, true);
- return true;
- }
- }
+ return true;
+ }
+ }
}
@@ -9,6 +9,7 @@ public enum TaskExecutionStatus
{
Pending,
FailedToPrepare,
+ Prepared,
Successful,
Failed,
RequiresAppRestart,
@@ -27,8 +28,7 @@ public interface IUpdateTask : INauFieldsHolder
/// the final trivial operations required to actually perform the update.
/// </summary>
/// <param name="source">An update source object, in case more data is required</param>
- /// <returns>True if successful, false otherwise</returns>
- bool Prepare(Sources.IUpdateSource source);
+ void Prepare(Sources.IUpdateSource source);
/// <summary>
/// Execute the update. After all preparation is done, this call should be quite a short one
@@ -42,12 +42,11 @@ protected object ValueToSet
return null;
}
}
- private object originalValue;
+ private object _originalValue;
- public override bool Prepare(Sources.IUpdateSource source)
+ public override void Prepare(Sources.IUpdateSource source)
{
// No preparation required
- return true;
}
public override TaskExecutionStatus Execute(bool coldRun /* unused */)
@@ -59,7 +58,7 @@ public override TaskExecutionStatus Execute(bool coldRun /* unused */)
// Get the current value and store in case we need to rollback
// This is also used to prematurely detect incorrect key and value paths
// Any exception thrown in this stage would just keep this task in Pending state
- originalValue = Registry.GetValue(KeyName, KeyValueName, null);
+ _originalValue = Registry.GetValue(KeyName, KeyValueName, null);
try
{
@@ -76,7 +75,7 @@ public override TaskExecutionStatus Execute(bool coldRun /* unused */)
public override bool Rollback()
{
- Registry.SetValue(KeyName, KeyValueName, originalValue);
+ Registry.SetValue(KeyName, KeyValueName, _originalValue);
return true;
}
}
@@ -28,7 +28,7 @@ public virtual void OnProgress(UpdateProgressInfo pi)
ProgressDelegate(pi);
}
- public abstract bool Prepare(IUpdateSource source);
+ public abstract void Prepare(IUpdateSource source);
public abstract TaskExecutionStatus Execute(bool coldRun);
public abstract bool Rollback();
}
@@ -28,6 +28,7 @@ private UpdateManager()
UpdatesToApply = new List<IUpdateTask>();
ApplicationPath = Process.GetCurrentProcess().MainModule.FileName;
UpdateFeedReader = new NauXmlFeedReader();
+ Logger = new Logger();
Config = new NauConfigurations
{
TempFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()),
@@ -80,8 +81,8 @@ public enum UpdateProcessState
public IUpdateSource UpdateSource { get; set; }
public IUpdateFeedReader UpdateFeedReader { get; set; }
-
- private Logger _logger = new Logger();
+
+ public Logger Logger { get; private set; }
public IEnumerable<IUpdateTask> Tasks { get { return UpdatesToApply; } }
@@ -231,7 +232,14 @@ public void PrepareUpdates()
throw new InvalidOperationException("No updates to prepare");
if (!Directory.Exists(Config.TempFolder))
+ {
+ Logger.Log("Creating Temp directory {0}", Config.TempFolder);
Directory.CreateDirectory(Config.TempFolder);
+ }
+ else
+ {
+ Logger.Log("Using existing Temp directory {0}", Config.TempFolder);
+ }
foreach (var task in UpdatesToApply)
{
@@ -241,11 +249,18 @@ public void PrepareUpdates()
var t = task;
task.ProgressDelegate += status => TaskProgressCallback(status, t);
- if (!task.Prepare(UpdateSource))
+ try
{
- task.ExecutionStatus = TaskExecutionStatus.FailedToPrepare; // TODO: lose this and rely on exceptions thrown from within Prepare()
- throw new UpdateProcessFailedException("Failed to prepare task: " + task.Description);
+ task.Prepare(UpdateSource);
}
+ catch (Exception ex)
+ {
+ task.ExecutionStatus = TaskExecutionStatus.FailedToPrepare;
+ Logger.Log(ex);
+ throw new UpdateProcessFailedException("Failed to prepare task: " + task.Description, ex);
+ }
+
+ task.ExecutionStatus = TaskExecutionStatus.Prepared;
}
State = UpdateProcessState.Prepared;
@@ -432,7 +447,7 @@ public void ApplyUpdates(bool relaunchApplication, bool updaterDoLogging, bool u
AppPath = ApplicationPath,
WorkingDirectory = Environment.CurrentDirectory,
RelaunchApplication = relaunchApplication,
- LogItems = _logger.LogItems,
+ LogItems = Logger.LogItems,
};
NauIpc.ExtractUpdaterFromResource(Config.TempFolder, Instance.Config.UpdateExecutableName);
@@ -487,7 +502,7 @@ public void ReinstateIfRestarted()
{
Config = dto.Configs;
UpdatesToApply = dto.Tasks;
- _logger = new Logger(dto.LogItems);
+ Logger = new Logger(dto.LogItems);
State = UpdateProcessState.AfterRestart;
}
}
@@ -23,7 +23,7 @@ private static void Main()
string logFile = string.Empty;
_args = ArgumentsParser.Get();
- _logger = new Logger();
+ _logger = UpdateManager.Instance.Logger;
_args.ParseCommandLineArgs();
if (_args.ShowConsole)
{
@@ -76,9 +76,9 @@ private static void Main()
if (dto.LogItems != null) // shouldn't really happen
{
- dto.LogItems.AddRange(_logger.LogItems);
- _logger = new Logger(dto.LogItems);
+ _logger.LogItems.InsertRange(0, dto.LogItems);
}
+ dto.LogItems = _logger.LogItems;
// Get some required environment variables
string appPath = dto.AppPath;
@@ -235,7 +235,7 @@ private static void Log(Exception ex)
{
_console.WriteLine("*********************************");
_console.WriteLine(" An error has occurred:");
- _console.WriteLine(" " + ex.Message);
+ _console.WriteLine(" " + ex);
_console.WriteLine("*********************************");
_console.WriteLine();

0 comments on commit 96fe742

Please sign in to comment.