diff --git a/FeedBuilder/FeedBuilder.csproj b/FeedBuilder/FeedBuilder.csproj
index aa6b2fd3..8fcafd30 100644
--- a/FeedBuilder/FeedBuilder.csproj
+++ b/FeedBuilder/FeedBuilder.csproj
@@ -12,7 +12,7 @@
FeedBuilder
512
WindowsForms
- v2.0
+ v3.5
1591
@@ -136,6 +136,7 @@
+
SettingsSingleFileGenerator
Settings.Designer.cs
@@ -153,4 +154,4 @@
-
+
\ No newline at end of file
diff --git a/FeedBuilder/Properties/Resources.Designer.cs b/FeedBuilder/Properties/Resources.Designer.cs
index 8408bebd..12793502 100644
--- a/FeedBuilder/Properties/Resources.Designer.cs
+++ b/FeedBuilder/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.269
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
diff --git a/FeedBuilder/Properties/Settings.Designer.cs b/FeedBuilder/Properties/Settings.Designer.cs
index f7457cc0..263c0a84 100644
--- a/FeedBuilder/Properties/Settings.Designer.cs
+++ b/FeedBuilder/Properties/Settings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.269
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -12,7 +12,7 @@ namespace FeedBuilder {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -37,6 +37,7 @@ public string BaseURL {
}
[global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Configuration.SettingsProviderAttribute(typeof(FeedBuilder.FeedBuilderSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool CleanUp {
@@ -142,6 +143,9 @@ public bool IgnoreDebugSymbols {
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(FeedBuilder.FeedBuilderSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("\r\n\r\n *.pdb\r\n *.config\r\n")]
public global::System.Collections.Specialized.StringCollection IgnoreFiles {
get {
return ((global::System.Collections.Specialized.StringCollection)(this["IgnoreFiles"]));
diff --git a/FeedBuilder/app.config b/FeedBuilder/app.config
new file mode 100644
index 00000000..2fa6e95d
--- /dev/null
+++ b/FeedBuilder/app.config
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj b/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj
index b1ac3823..555394ac 100644
--- a/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj
+++ b/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj
@@ -10,7 +10,7 @@
Properties
NAppUpdate.Framework
NAppUpdate.Framework
- v2.0
+ v3.5
512
true
NAppUpdate.snk
@@ -33,6 +33,7 @@
false
false
true
+
true
@@ -101,6 +102,7 @@
+
diff --git a/src/NAppUpdate.Framework/UpdateManager.cs b/src/NAppUpdate.Framework/UpdateManager.cs
index 1fc1346d..91a7e39e 100644
--- a/src/NAppUpdate.Framework/UpdateManager.cs
+++ b/src/NAppUpdate.Framework/UpdateManager.cs
@@ -506,10 +506,20 @@ public void ApplyUpdates(bool relaunchApplication, bool updaterDoLogging, bool u
public void ReinstateIfRestarted()
{
+ if (!IsAfterRestart())
+ {
+ return;
+ }
+
lock (UpdatesToApply)
{
- var dto = NauIpc.ReadDto(Config.UpdateProcessName) as NauIpc.NauDto;
- if (dto == null) return;
+ NauIpc.NauDto dto = NauIpc.ReadDto(Config.UpdateProcessName);
+
+ if (dto == null)
+ {
+ return;
+ }
+
Config = dto.Configs;
UpdatesToApply = dto.Tasks;
Logger = new Logger(dto.LogItems);
@@ -581,5 +591,18 @@ public void CleanUp()
ShouldStop = false;
}
}
+
+ private bool IsAfterRestart()
+ {
+ foreach (string arg in Environment.GetCommandLineArgs())
+ {
+ if (arg == "-nappupdate-afterrestart")
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/src/NAppUpdate.Framework/Updater/updater.exe b/src/NAppUpdate.Framework/Updater/updater.exe
index 0519ecba..94c4caa2 100644
Binary files a/src/NAppUpdate.Framework/Updater/updater.exe and b/src/NAppUpdate.Framework/Updater/updater.exe differ
diff --git a/src/NAppUpdate.Framework/Utils/NauIpc.cs b/src/NAppUpdate.Framework/Utils/NauIpc.cs
index 91f84a24..52b08c54 100644
--- a/src/NAppUpdate.Framework/Utils/NauIpc.cs
+++ b/src/NAppUpdate.Framework/Utils/NauIpc.cs
@@ -9,6 +9,7 @@
using System.Runtime.Serialization.Formatters.Binary;
using NAppUpdate.Framework.Common;
using NAppUpdate.Framework.Tasks;
+using System.IO.Pipes;
namespace NAppUpdate.Framework.Utils
{
@@ -29,158 +30,76 @@ internal class NauDto
public bool RelaunchApplication { get; set; }
}
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern SafeFileHandle CreateNamedPipe(
- String pipeName,
- uint dwOpenMode,
- uint dwPipeMode,
- uint nMaxInstances,
- uint nOutBufferSize,
- uint nInBufferSize,
- uint nDefaultTimeOut,
- IntPtr lpSecurityAttributes);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern int ConnectNamedPipe(
- SafeFileHandle hNamedPipe,
- IntPtr lpOverlapped);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern SafeFileHandle CreateFile(
- String pipeName,
- uint dwDesiredAccess,
- uint dwShareMode,
- IntPtr lpSecurityAttributes,
- uint dwCreationDisposition,
- uint dwFlagsAndAttributes,
- IntPtr hTemplate);
-
- //private const uint DUPLEX = (0x00000003);
- private const uint WRITE_ONLY = (0x00000002);
- private const uint FILE_FLAG_OVERLAPPED = (0x40000000);
-
- const uint GENERIC_READ = (0x80000000);
- //static readonly uint GENERIC_WRITE = (0x40000000);
- const uint OPEN_EXISTING = 3;
-
- //Which really isn't an error...
- const uint ERROR_PIPE_CONNECTED = 535;
-
- internal static string GetPipeName(string syncProcessName)
- {
- return string.Format("\\\\.\\pipe\\{0}", syncProcessName);
- }
-
- private class State
- {
- public readonly EventWaitHandle eventWaitHandle;
- public int result { get; set; }
- public SafeFileHandle clientPipeHandle { get; set; }
- public Exception exception;
-
- public State()
- {
- eventWaitHandle = new ManualResetEvent(false);
- }
- }
-
- internal static uint BUFFER_SIZE = 4096;
+ private const int PIPE_TIMEOUT = 15000;
+ ///
+ /// Launches the specifies process and sends the dto object to it using a named pipe
+ ///
+ /// Dto object to send
+ /// Process info for the process to start
+ /// Name of the pipe to write to
+ /// The started process
public static Process LaunchProcessAndSendDto(NauDto dto, ProcessStartInfo processStartInfo, string syncProcessName)
{
Process p;
- State state = new State();
-
- using (state.clientPipeHandle = CreateNamedPipe(
- GetPipeName(syncProcessName),
- WRITE_ONLY | FILE_FLAG_OVERLAPPED,
- 0,
- 1, // 1 max instance (only the updater utility is expected to connect)
- BUFFER_SIZE,
- BUFFER_SIZE,
- 0,
- IntPtr.Zero))
+
+ using (NamedPipeServerStream pipe = new NamedPipeServerStream(syncProcessName, PipeDirection.Out, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous))
{
- //failed to create named pipe
- if (state.clientPipeHandle.IsInvalid)
+ p = Process.Start(processStartInfo);
+
+ if (p == null)
{
- throw new Exception("Launch process client: Failed to create named pipe, handle is invalid.");
+ throw new ProcessStartFailedException("The process failed to start");
}
- // This will throw Win32Exception if the user denies UAC
- p = Process.Start(processStartInfo);
-
- ThreadPool.QueueUserWorkItem(ConnectPipe, state);
- //A rather arbitary five seconds, perhaps better to be user configurable at some point?
- state.eventWaitHandle.WaitOne(10000);
+ var asyncResult = pipe.BeginWaitForConnection(null, null);
- //failed to connect client pipe
- if (state.result == 0)
+ if (asyncResult.AsyncWaitHandle.WaitOne(PIPE_TIMEOUT))
{
- throw new Exception("Launch process client: Failed to connect to named pipe", state.exception);
+ pipe.EndWaitForConnection(asyncResult);
+
+ BinaryFormatter formatter = new BinaryFormatter();
+ formatter.Serialize(pipe, dto);
}
+ else if (p.HasExited)
+ {
+ Type exceptionType = Marshal.GetExceptionForHR(p.ExitCode).GetType();
- //client connection successfull
- using (var fStream = new FileStream(state.clientPipeHandle, FileAccess.Write, (int)BUFFER_SIZE, true))
+ throw new TimeoutException(string.Format("The NamedPipeServerStream timed out waiting for a named pipe connection, " +
+ "but the process has exited with exit code: {0} ({1})", p.ExitCode, exceptionType.FullName));
+ }
+ else
{
- new BinaryFormatter().Serialize(fStream, dto);
- fStream.Flush();
- fStream.Close();
+ throw new TimeoutException("The NamedPipeServerStream timed out waiting for a named pipe connection.");
}
}
return p;
}
- internal static void ConnectPipe(object stateObject)
+ ///
+ /// Reads the dto object from the named pipe
+ ///
+ /// Name of the pipe to read from
+ /// The dto object read from the pipe
+ public static NauDto ReadDto(string syncProcessName)
{
- State state = (State)stateObject;
+ NauDto dto;
- try
- {
- state.result = ConnectNamedPipe(state.clientPipeHandle, IntPtr.Zero);
- }
- catch (Exception e)
+ using (NamedPipeClientStream pipe = new NamedPipeClientStream(".", syncProcessName, PipeDirection.In, PipeOptions.Asynchronous))
{
- state.exception = e;
- }
+ pipe.Connect(PIPE_TIMEOUT);
- int error = Marshal.GetLastWin32Error();
- //Check for the oddball: ERROR - PIPE CONNECTED
- //Ref: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365146%28v=vs.85%29.aspx
- if (error == ERROR_PIPE_CONNECTED)
- {
- state.result = 1;
- }
- else if (error != 0)
- {
- state.exception = new Win32Exception(error);
+ BinaryFormatter formatter = new BinaryFormatter();
+ dto = formatter.Deserialize(pipe) as NauDto;
}
- state.eventWaitHandle.Set(); // signal we're done
- }
-
-
- internal static object ReadDto(string syncProcessName)
- {
- using (SafeFileHandle pipeHandle = CreateFile(
- GetPipeName(syncProcessName),
- GENERIC_READ,
- 0,
- IntPtr.Zero,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- IntPtr.Zero))
+ if (dto == null || dto.Configs == null)
{
-
- if (pipeHandle.IsInvalid)
- return null;
-
- using (var fStream = new FileStream(pipeHandle, FileAccess.Read, (int)BUFFER_SIZE, true))
- {
- return new BinaryFormatter().Deserialize(fStream);
- }
+ throw new Exception("Failed to read the dto from the pipe stream");
}
+
+ return dto;
}
internal static void ExtractUpdaterFromResource(string updaterPath, string hostExeName)
@@ -212,4 +131,4 @@ internal static void ExtractUpdaterFromResource(string updaterPath, string hostE
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NAppUpdate.Framework/Utils/ProcessStartFailedException.cs b/src/NAppUpdate.Framework/Utils/ProcessStartFailedException.cs
new file mode 100644
index 00000000..fa52f874
--- /dev/null
+++ b/src/NAppUpdate.Framework/Utils/ProcessStartFailedException.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace NAppUpdate.Framework.Utils
+{
+ ///
+ /// Thrown if the Process.Start() call returns null, e.g. the updater process fails to start at all.
+ ///
+ internal class ProcessStartFailedException : Exception
+ {
+ public ProcessStartFailedException(string message) : base(message) { }
+ }
+
+}
diff --git a/src/NAppUpdate.Updater/AppStart.cs b/src/NAppUpdate.Updater/AppStart.cs
index 5edc9a2b..825206db 100644
--- a/src/NAppUpdate.Updater/AppStart.cs
+++ b/src/NAppUpdate.Updater/AppStart.cs
@@ -8,6 +8,7 @@
using NAppUpdate.Framework.Common;
using NAppUpdate.Framework.Tasks;
using NAppUpdate.Framework.Utils;
+using System.Runtime.InteropServices;
namespace NAppUpdate.Updater
{
@@ -16,15 +17,43 @@ internal static class AppStart
private static ArgumentsParser _args;
private static Logger _logger;
private static ConsoleForm _console;
+ private static NauIpc.NauDto _dto;
+ private static string _logFilePath = string.Empty;
+ private static string _workingDir = string.Empty;
+ private static bool _appRunning = true;
private static void Main()
{
- //Debugger.Launch();
- string tempFolder = string.Empty;
- string logFile = string.Empty;
- _args = ArgumentsParser.Get();
+ try
+ {
+ Setup();
+ PerformUpdates();
+ }
+ catch (Exception ex)
+ {
+ Environment.ExitCode = Marshal.GetHRForException(ex);
+
+ Log(ex);
+
+ if (!_appRunning && !_args.Log && !_args.ShowConsole)
+ {
+ MessageBox.Show(ex.ToString());
+ }
+
+ EventLog.WriteEntry("NAppUpdate.Updater", ex.ToString(), EventLogEntryType.Error);
+ }
+ finally
+ {
+ Teardown();
+ }
+ }
+ private static void Setup()
+ {
+ _workingDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
_logger = UpdateManager.Instance.Logger;
+ _args = ArgumentsParser.Get();
+
_args.ParseCommandLineArgs();
if (_args.ShowConsole)
{
@@ -34,212 +63,191 @@ private static void Main()
Log("Starting to process cold updates...");
- var workingDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
if (_args.Log)
{
// Setup a temporary location for the log file, until we can get the DTO
- logFile = Path.Combine(workingDir, @"NauUpdate.log");
+ _logFilePath = Path.Combine(_workingDir, @"NauUpdate.log");
}
+ }
- try
+ private static void PerformUpdates()
+ {
+ string syncProcessName = _args.ProcessName;
+
+ if (string.IsNullOrEmpty(syncProcessName))
{
- // Get the update process name, to be used to create a named pipe and to wait on the application
- // to quit
- string syncProcessName = _args.ProcessName;
- if (string.IsNullOrEmpty(syncProcessName)) //Application.Exit();
- throw new ArgumentException("The command line needs to specify the mutex of the program to update.", "ar" + "gs");
+ throw new ArgumentException("Required command line argument is missing", "ProcessName");
+ }
- Log("Update process name: '{0}'", syncProcessName);
+ Log("Update process name: '{0}'", syncProcessName);
- // Load extra assemblies to the app domain, if present
- var availableAssemblies = FileSystem.GetFiles(workingDir, "*.exe|*.dll", SearchOption.TopDirectoryOnly);
- foreach (var assemblyPath in availableAssemblies)
- {
- Log("Loading {0}", assemblyPath);
+ // Load extra assemblies to the app domain, if present
+ var availableAssemblies = FileSystem.GetFiles(_workingDir, "*.exe|*.dll", SearchOption.TopDirectoryOnly);
+ foreach (var assemblyPath in availableAssemblies)
+ {
+ Log("Loading {0}", assemblyPath);
- if (assemblyPath.Equals(Assembly.GetEntryAssembly().Location, StringComparison.InvariantCultureIgnoreCase) || assemblyPath.EndsWith("NAppUpdate.Framework.dll"))
- {
- Log("\tSkipping (part of current execution)");
- continue;
- }
+ if (assemblyPath.Equals(Assembly.GetEntryAssembly().Location, StringComparison.InvariantCultureIgnoreCase) || assemblyPath.EndsWith("NAppUpdate.Framework.dll"))
+ {
+ Log("\tSkipping (part of current execution)");
+ continue;
+ }
- try
- {
- // ReSharper disable UnusedVariable
- var assembly = Assembly.LoadFile(assemblyPath);
- // ReSharper restore UnusedVariable
- }
- catch (BadImageFormatException ex)
- {
- Log("\tSkipping due to an error: {0}", ex.Message);
- }
+ try
+ {
+ // ReSharper disable UnusedVariable
+ var assembly = Assembly.LoadFile(assemblyPath);
+ // ReSharper restore UnusedVariable
+ }
+ catch (BadImageFormatException ex)
+ {
+ Log("\tSkipping due to an error: {0}", ex.Message);
}
+ }
- // Connect to the named pipe and retrieve the updates list
- var dto = NauIpc.ReadDto(syncProcessName) as NauIpc.NauDto;
+ // Connect to the named pipe and retrieve the updates list
+ _dto = NauIpc.ReadDto(syncProcessName);
- // Make sure we start updating only once the application has completely terminated
- Thread.Sleep(1000); // Let's even wait a bit
- bool createdNew;
- using (var mutex = new Mutex(false, syncProcessName + "Mutex", out createdNew))
+ // Make sure we start updating only once the application has completely terminated
+ Thread.Sleep(1000); // Let's even wait a bit
+ bool createdNew;
+ using (var mutex = new Mutex(false, syncProcessName + "Mutex", out createdNew))
+ {
+ try
{
- try
- {
- if (!createdNew) mutex.WaitOne();
- }
- catch (AbandonedMutexException)
+ if (!createdNew)
{
- // An abandoned mutex is exactly what we are expecting...
- }
- finally
- {
- Log("The application has terminated (as expected)");
+ mutex.WaitOne();
}
}
+ catch (AbandonedMutexException)
+ {
+ // An abandoned mutex is exactly what we are expecting...
+ }
+ finally
+ {
+ Log("The application has terminated (as expected)");
+ _appRunning = false;
+ }
+ }
- bool updateSuccessful = true;
-
- if (dto == null || dto.Configs == null) throw new Exception("Invalid DTO received");
+ _logger.LogItems.InsertRange(0, _dto.LogItems);
+ _dto.LogItems = _logger.LogItems;
- if (dto.LogItems != null) // shouldn't really happen
- _logger.LogItems.InsertRange(0, dto.LogItems);
- dto.LogItems = _logger.LogItems;
+ // Get some required environment variables
+ string appPath = _dto.AppPath;
+ string appDir = _dto.WorkingDirectory ?? Path.GetDirectoryName(appPath) ?? string.Empty;
- // Get some required environment variables
- string appPath = dto.AppPath;
- string appDir = dto.WorkingDirectory ?? Path.GetDirectoryName(appPath) ?? string.Empty;
- tempFolder = dto.Configs.TempFolder;
- string backupFolder = dto.Configs.BackupFolder;
- bool relaunchApp = dto.RelaunchApplication;
+ if (!string.IsNullOrEmpty(_dto.AppPath))
+ {
+ _logFilePath = Path.Combine(Path.GetDirectoryName(_dto.AppPath), @"NauUpdate.log"); // now we can log to a more accessible location
+ }
- if (!string.IsNullOrEmpty(dto.AppPath)) logFile = Path.Combine(Path.GetDirectoryName(dto.AppPath), @"NauUpdate.log"); // now we can log to a more accessible location
+ if (_dto.Tasks == null)
+ {
+ throw new Exception("The Task list received in the dto is null");
+ }
+ else if (_dto.Tasks.Count == 0)
+ {
+ throw new Exception("The Task list received in the dto is empty");
+ }
- if (dto.Tasks == null || dto.Tasks.Count == 0) throw new Exception("Could not find the updates list (or it was empty).");
+ Log("Got {0} task objects", _dto.Tasks.Count);
- Log("Got {0} task objects", dto.Tasks.Count);
+ // Perform the actual off-line update process
+ foreach (var t in _dto.Tasks)
+ {
+ Log("Task \"{0}\": {1}", t.Description, t.ExecutionStatus);
- //This can be handy if you're trying to debug the updater.exe!
- //#if (DEBUG)
+ if (t.ExecutionStatus != TaskExecutionStatus.RequiresAppRestart && t.ExecutionStatus != TaskExecutionStatus.RequiresPrivilegedAppRestart)
{
- if (_args.ShowConsole)
- {
- _console.WriteLine();
- _console.WriteLine("Pausing to attach debugger. Press any key to continue.");
- _console.ReadKey();
- }
+ Log("\tSkipping");
+ continue;
+ }
+
+ Exception exception = null;
+ try
+ {
+ Log("\tExecuting...");
+ t.ExecutionStatus = t.Execute(true);
+ }
+ catch (Exception ex)
+ {
+ t.ExecutionStatus = TaskExecutionStatus.Failed;
+ exception = ex;
}
- //#endif
- // Perform the actual off-line update process
- foreach (var t in dto.Tasks)
+ if (t.ExecutionStatus != TaskExecutionStatus.Successful)
{
- Log("Task \"{0}\": {1}", t.Description, t.ExecutionStatus);
+ string taskFailedMessage = string.Format("Update failed, task execution failed, description: {0}, execution status: {1}", t.Description, t.ExecutionStatus);
+ throw new Exception(taskFailedMessage, exception);
+ }
+ }
- if (t.ExecutionStatus != TaskExecutionStatus.RequiresAppRestart && t.ExecutionStatus != TaskExecutionStatus.RequiresPrivilegedAppRestart)
- {
- Log("\tSkipping");
- continue;
- }
+ Log("Finished successfully");
+ Log("Removing backup folder");
- Log("\tExecuting...");
+ if (Directory.Exists(_dto.Configs.BackupFolder))
+ {
+ FileSystem.DeleteDirectory(_dto.Configs.BackupFolder);
+ }
- // TODO: Better handling on failure: logging, rollbacks
- try
- {
- t.ExecutionStatus = t.Execute(true);
- }
- catch (Exception ex)
- {
- Log(ex);
- updateSuccessful = false;
- t.ExecutionStatus = TaskExecutionStatus.Failed;
- }
+ // Start the application only if requested to do so
+ if (_dto.RelaunchApplication)
+ {
+ Log("Re-launching process {0} with working dir {1}", appPath, appDir);
- if (t.ExecutionStatus == TaskExecutionStatus.Successful) continue;
- Log("\tTask execution failed");
- updateSuccessful = false;
- break;
- }
+ bool useShellExecute = !_args.ShowConsole;
- if (updateSuccessful)
+ ProcessStartInfo info = new ProcessStartInfo
{
- Log("Finished successfully");
- Log("Removing backup folder");
- if (Directory.Exists(backupFolder)) FileSystem.DeleteDirectory(backupFolder);
- }
- else
+ UseShellExecute = useShellExecute,
+ WorkingDirectory = appDir,
+ FileName = appPath,
+ Arguments = "-nappupdate-afterrestart"
+ };
+
+ try
{
- MessageBox.Show("Update Failed");
- Log(Logger.SeverityLevel.Error, "Update failed");
+ NauIpc.LaunchProcessAndSendDto(_dto, info, syncProcessName);
+ _appRunning = true;
}
-
- // Start the application only if requested to do so
- if (relaunchApp)
+ catch (Exception ex)
{
- Log("Re-launching process {0} with working dir {1}", appPath, appDir);
- ProcessStartInfo info;
- if (_args.ShowConsole)
- {
- info = new ProcessStartInfo
- {
- UseShellExecute = false,
- WorkingDirectory = appDir,
- FileName = appPath,
- };
- }
- else
- {
- info = new ProcessStartInfo
- {
- UseShellExecute = true,
- WorkingDirectory = appDir,
- FileName = appPath,
- };
- }
-
- try
- {
- NauIpc.LaunchProcessAndSendDto(dto, info, syncProcessName);
- }
- catch (Exception ex)
- {
- throw new UpdateProcessFailedException("Unable to relaunch application and/or send DTO", ex);
- }
+ throw new UpdateProcessFailedException("Unable to relaunch application and/or send DTO", ex);
}
-
- Log("All done");
- //Application.Exit();
}
- catch (Exception ex)
+ }
+
+ private static void Teardown()
+ {
+ if (_args.Log)
{
- // supressing catch because if at any point we get an error the update has failed
- Log(ex);
+ // at this stage we can't make any assumptions on correctness of the path
+ FileSystem.CreateDirectoryStructure(_logFilePath, true);
+ _logger.Dump(_logFilePath);
}
- finally
+
+ if (_args.ShowConsole)
{
if (_args.Log)
{
- // at this stage we can't make any assumptions on correctness of the path
- FileSystem.CreateDirectoryStructure(logFile, true);
- _logger.Dump(logFile);
- }
-
- if (_args.ShowConsole)
- {
- if (_args.Log)
- {
- _console.WriteLine();
- _console.WriteLine("Log file was saved to {0}", logFile);
- _console.WriteLine();
- }
_console.WriteLine();
- _console.WriteLine("Press any key or close this window to exit.");
- _console.ReadKey();
+ _console.WriteLine("Log file was saved to {0}", _logFilePath);
+ _console.WriteLine();
}
- if (!string.IsNullOrEmpty(tempFolder)) SelfCleanUp(tempFolder);
- Application.Exit();
+ _console.WriteLine();
+ _console.WriteLine("Press any key or close this window to exit.");
+ _console.ReadKey();
+ }
+
+ if (_dto != null && _dto.Configs != null & !string.IsNullOrEmpty(_dto.Configs.TempFolder))
+ {
+ SelfCleanUp(_dto.Configs.TempFolder);
}
+
+ Application.Exit();
}
private static void SelfCleanUp(string tempFolder)
@@ -274,9 +282,13 @@ private static void Log(Logger.SeverityLevel severity, string message, params ob
message = string.Format(message, args);
_logger.Log(severity, message);
- if (_args.ShowConsole) _console.WriteLine(message);
- Application.DoEvents();
+ if (_args.ShowConsole)
+ {
+ _console.WriteLine(message);
+
+ Application.DoEvents();
+ }
}
private static void Log(Exception ex)
@@ -292,9 +304,9 @@ private static void Log(Exception ex)
_console.WriteLine();
_console.WriteLine("The updater will close when you close this window.");
- }
- Application.DoEvents();
+ Application.DoEvents();
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NAppUpdate.Updater/NAppUpdate.Updater.csproj b/src/NAppUpdate.Updater/NAppUpdate.Updater.csproj
index fba3a29d..bfdae1e2 100644
--- a/src/NAppUpdate.Updater/NAppUpdate.Updater.csproj
+++ b/src/NAppUpdate.Updater/NAppUpdate.Updater.csproj
@@ -10,7 +10,7 @@
Properties
NAppUpdate.Updater
NAppUpdate.Updater
- v2.0
+ v3.5
512
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
4
@@ -36,6 +36,7 @@
false
true
OnBuildSuccess
+
true
diff --git a/src/NAppUpdate.Updater/Properties/Settings.Designer.cs b/src/NAppUpdate.Updater/Properties/Settings.Designer.cs
index c10ec226..d8b18369 100644
--- a/src/NAppUpdate.Updater/Properties/Settings.Designer.cs
+++ b/src/NAppUpdate.Updater/Properties/Settings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.225
+// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -12,7 +12,7 @@ namespace NAppUpdate.Updater.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/src/NAppUpdate.Updater/app.config b/src/NAppUpdate.Updater/app.config
index 0df7832f..ea93c858 100644
--- a/src/NAppUpdate.Updater/app.config
+++ b/src/NAppUpdate.Updater/app.config
@@ -1,3 +1,3 @@
-
+