diff --git a/BlazamSetup/App.xaml.cs b/BlazamSetup/App.xaml.cs
index b028649..ddd9e8b 100644
--- a/BlazamSetup/App.xaml.cs
+++ b/BlazamSetup/App.xaml.cs
@@ -14,6 +14,7 @@
using Org.BouncyCastle.Bcpg.OpenPgp;
using Serilog;
using Serilog.Events;
+using System.Windows.Threading;
namespace BlazamSetup
{
@@ -44,7 +45,7 @@ protected override void OnStartup(StartupEventArgs args)
.Enrich.WithMachineName()
.Enrich.WithEnvironmentName()
.Enrich.WithEnvironmentUserName()
-
+ .Enrich.WithProperty("Application Name","Blazam Setup")
.WriteTo.File(InstallationConfiguraion.SetupTempDirectory + @"setuplog.txt",
rollingInterval: RollingInterval.Infinite,
@@ -55,8 +56,9 @@ protected override void OnStartup(StartupEventArgs args)
//lc.WriteTo.Console();
lc.Filter.ByExcluding(e => e.Level == LogEventLevel.Information).WriteTo.Console();
})
- .WriteTo.Seq("http://logs.blazam.org:5341", apiKey: "S3JdoIIfIKcX4L3howh1", restrictedToMinimumLevel: LogEventLevel.Warning)
+ .WriteTo.Seq("http://logs.blazam.org:5341", apiKey: "S3JdoIIfIKcX4L3howh1", restrictedToMinimumLevel: LogEventLevel.Information)
.CreateLogger();
+ SetupUnhandledExceptionHandling();
StartupArgs = args;
if (!Debugger.IsAttached)
@@ -74,7 +76,7 @@ protected override void OnStartup(StartupEventArgs args)
}
-
+
private void SetupAppCenter()
{
try
@@ -150,5 +152,61 @@ public static bool IsRunningAsAdministrator()
// Return TRUE if user is in role "Administrator"
return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
}
+
+ private void SetupUnhandledExceptionHandling()
+ {
+ // Catch exceptions from all threads in the AppDomain.
+ AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
+ ShowUnhandledException(args.ExceptionObject as Exception, "AppDomain.CurrentDomain.UnhandledException", false);
+
+ // Catch exceptions from each AppDomain that uses a task scheduler for async operations.
+ TaskScheduler.UnobservedTaskException += (sender, args) =>
+ ShowUnhandledException(args.Exception, "TaskScheduler.UnobservedTaskException", false);
+
+ // Catch exceptions from a single specific UI dispatcher thread.
+ Dispatcher.UnhandledException += (sender, args) =>
+ {
+ // If we are debugging, let Visual Studio handle the exception and take us to the code that threw it.
+ if (!Debugger.IsAttached)
+ {
+ args.Handled = true;
+ ShowUnhandledException(args.Exception, "Dispatcher.UnhandledException", true);
+ }
+ };
+
+ // Catch exceptions from the main UI dispatcher thread.
+ // Typically we only need to catch this OR the Dispatcher.UnhandledException.
+ // Handling both can result in the exception getting handled twice.
+ //Application.Current.DispatcherUnhandledException += (sender, args) =>
+ //{
+ // // If we are debugging, let Visual Studio handle the exception and take us to the code that threw it.
+ // if (!Debugger.IsAttached)
+ // {
+ // args.Handled = true;
+ // ShowUnhandledException(args.Exception, "Application.Current.DispatcherUnhandledException", true);
+ // }
+ //};
+ }
+
+ void ShowUnhandledException(Exception e, string unhandledExceptionType, bool promptUserForShutdown)
+ {
+ Log.Error("Uncaught Exception: {@Error}", e);
+
+ var messageBoxTitle = $"Fatal Error!";
+ var messageBoxMessage = $"We apologize for the error. A report has been sent to the developers.";
+ var messageBoxButtons = MessageBoxButton.OK;
+
+ if (promptUserForShutdown)
+ {
+ messageBoxMessage += "\n\nNormally the installer would close now. Should we close it?";
+ messageBoxButtons = MessageBoxButton.YesNo;
+ }
+
+ // Let the user decide if the app should die or not (if applicable).
+ if (MessageBox.Show(messageBoxMessage, messageBoxTitle, messageBoxButtons) == MessageBoxResult.Yes)
+ {
+ Application.Current.Shutdown();
+ }
+ }
}
}
diff --git a/BlazamSetup/BlazamSetup.csproj b/BlazamSetup/BlazamSetup.csproj
index 0d49cf5..dd59d66 100644
--- a/BlazamSetup/BlazamSetup.csproj
+++ b/BlazamSetup/BlazamSetup.csproj
@@ -423,6 +423,9 @@
InstallDirectory.xaml
+
+ InstalledActionDialog.xaml
+
LicenseAgreement.xaml
@@ -500,6 +503,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/BlazamSetup/Data/InstallationConfiguraion.cs b/BlazamSetup/Data/InstallationConfiguraion.cs
index f54e3f1..7e3fa7e 100644
--- a/BlazamSetup/Data/InstallationConfiguraion.cs
+++ b/BlazamSetup/Data/InstallationConfiguraion.cs
@@ -9,6 +9,7 @@
namespace BlazamSetup
{
public enum InstallType { IIS, Service }
+ public enum InstalledAction { Update, Repair,Remove}
public enum DBType { Sqlite, SQL, MySQL }
internal static class InstallationConfiguraion
{
@@ -49,5 +50,7 @@ internal static string InstallDirPath
public static string ProgramDataDir => Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + Path.DirectorySeparatorChar + "Blazam";
public static string SetupTempDirectory => Path.GetTempPath() + "BlazamSetup\\";
+
+ public static InstalledAction InstalledAction { get; internal set; }
}
}
diff --git a/BlazamSetup/MainWindow.xaml b/BlazamSetup/MainWindow.xaml
index c29ea08..9e747aa 100644
--- a/BlazamSetup/MainWindow.xaml
+++ b/BlazamSetup/MainWindow.xaml
@@ -16,7 +16,7 @@
MouseDown="DockPanel_MouseDown"
VerticalAlignment="Top"
- LastChildFill="True" Height="30" Background="Black">
+ LastChildFill="True" Height="30" Background="#202747">
@@ -60,7 +60,7 @@
-
+
diff --git a/BlazamSetup/MainWindow.xaml.cs b/BlazamSetup/MainWindow.xaml.cs
index f703009..5ed26ca 100644
--- a/BlazamSetup/MainWindow.xaml.cs
+++ b/BlazamSetup/MainWindow.xaml.cs
@@ -1,6 +1,8 @@
using BlazamSetup.Services;
using BlazamSetup.Steps;
using BlazamSetup.Steps.Uninstall;
+using Microsoft.AppCenter.Ingestion.Models.Serialization;
+using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -28,26 +30,44 @@ public partial class MainWindow : Window
{
public MainWindow()
{
- InitializeComponent();
- CurrentDispatcher = Dispatcher;
+ try
+ {
+ InitializeComponent();
+ CurrentDispatcher = Dispatcher;
- InstallerFrame = Frame;
- LastStepButton = BackButton;
- NextStepButton = NextButton;
- MainWindow.InstallerFrame.ContentRendered += InstallerFrame_ContentRendered;
- if (RegistryService.InstallationExists)
- InstallationConfiguraion.ProductInformation = RegistryService.GetProductInformation();
+ InstallerFrame = Frame;
+ LastStepButton = BackButton;
+ NextStepButton = NextButton;
+ MainWindow.InstallerFrame.ContentRendered += InstallerFrame_ContentRendered;
+ if (RegistryService.InstallationExists)
+ InstallationConfiguraion.ProductInformation = RegistryService.GetProductInformation();
- if (App.StartupArgs.Args.Any(arg => arg.StartsWith("/u"))){
- MainWindow.InstallerFrame.Navigate(new WelcomeUninstall());
+ if (App.StartupArgs.Args.Any(arg => arg.StartsWith("/u")))
+ {
+ Log.Information("Uninstaller Started");
+ MainWindow.InstallerFrame.Navigate(new WelcomeUninstall());
- }
- else
- {
- MainWindow.InstallerFrame.Navigate(NavigationManager.CurrentPage);
+ }
+ else
+ {
+
+ Log.Information("Installer Started");
+ if (RegistryService.InstallationExists)
+ {
+ MainWindow.InstallerFrame.Navigate(new InstalledActionDialog());
- }
+ }
+ else
+ {
+ MainWindow.InstallerFrame.Navigate(NavigationManager.CurrentPage);
+
+ }
+ }
+ }catch (Exception ex)
+ {
+ Log.Error("Uncaught Exception: {@Error}", ex);
+ }
}
diff --git a/BlazamSetup/Services/DownloadService.cs b/BlazamSetup/Services/DownloadService.cs
index feeaf93..b54f931 100644
--- a/BlazamSetup/Services/DownloadService.cs
+++ b/BlazamSetup/Services/DownloadService.cs
@@ -1,4 +1,5 @@
using Octokit;
+using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -15,8 +16,8 @@ namespace BlazamSetup.Services
internal static class DownloadService
{
- public static string SetupTempDirectory = InstallationConfiguraion.SetupTempDirectory;
- public static string SourceDirectory = InstallationConfiguraion.SetupTempDirectory+"setup\\";
+ public static string SetupTempDirectory = Path.GetTempPath() + "BlazamSetup\\";
+ public static string SourceDirectory = Path.GetTempPath() + "BlazamSetup\\setup\\";
public static string UpdateFile = SetupTempDirectory + "blazam.zip";
private static ReleaseAsset latestRelease;
@@ -27,6 +28,8 @@ internal static class DownloadService
public static async Task Download()
{
+ Log.Information("Download started");
+
var githubclient = new GitHubClient(new ProductHeaderValue("BLAZAM-APP"));
@@ -114,47 +117,53 @@ public static async Task Download()
}
}
- return false;
+ return false;
}
- public static void CleanDownload()
+ public static void CleanDownload()
{
-
- cancellationTokenSource.Cancel();
- Task.Run(() => {
- int retries =5 ;
- while (retries-->0)
+
+ cancellationTokenSource.Cancel();
+ Task.Run(() =>
+ {
+ int retries = 5;
+ while (retries-- > 0)
+ {
+ try
{
- try
- {
- File.Delete(UpdateFile);
+ File.Delete(UpdateFile);
Directory.Delete(SetupTempDirectory, true);
- retries = 0;
+ retries = 0;
- }
- catch
- {
- Task.Delay(50).Wait();
- }
}
- });
-
-
+ catch
+ {
+ Task.Delay(50).Wait();
+ }
+ }
+ });
+
+
}
public static void CleanSource()
{
cancellationTokenSource.Cancel();
- Task.Run(() => {
+ Task.Run(() =>
+ {
int retries = 5;
while (retries-- > 0)
{
try
{
+ Log.Information("Cleaning old extracted files: " + SourceDirectory);
+
Directory.Delete(SourceDirectory, true);
retries = 0;
}
- catch
+ catch (Exception ex)
{
+ Log.Error("Error cleaning old installation files: {@Error}", ex);
+
Task.Delay(50).Wait();
}
}
@@ -162,14 +171,30 @@ public static void CleanSource()
}
- internal static void UnpackDownload()
+ internal static async Task UnpackDownload()
{
- CleanSource();
- Directory.CreateDirectory(SourceDirectory);
- ZipArchive download = new ZipArchive(File.OpenRead(UpdateFile));
- download.ExtractToDirectory(SourceDirectory);
- download.Dispose();
- File.Delete(UpdateFile);
+ return await Task.Run(() =>
+ {
+ try
+ {
+ Log.Information("Extracting files: " + SourceDirectory);
+
+ CleanSource();
+ Directory.CreateDirectory(SourceDirectory);
+ ZipArchive download = new ZipArchive(File.OpenRead(UpdateFile));
+ download.ExtractToDirectory(SourceDirectory);
+ download.Dispose();
+ File.Delete(UpdateFile);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Error unpacking download: {@Error}", ex);
+
+ }
+ return false;
+ });
+
}
}
}
diff --git a/BlazamSetup/Services/IISManageer.cs b/BlazamSetup/Services/IISManageer.cs
index 159dac0..a2512dd 100644
--- a/BlazamSetup/Services/IISManageer.cs
+++ b/BlazamSetup/Services/IISManageer.cs
@@ -1,12 +1,12 @@
-using Microsoft.Web.Administration;
+using Microsoft.AppCenter.Ingestion.Models.Serialization;
+using Microsoft.Web.Administration;
using Org.BouncyCastle.Bcpg.OpenPgp;
+using Serilog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
-using System.Text;
-using System.Threading.Tasks;
namespace BlazamSetup.Services
{
@@ -14,22 +14,36 @@ internal static class IISManager
{
public static bool CreateApplication()
{
- using (ServerManager serverManager = new ServerManager())
+ try
{
- if (!serverManager.Sites.Any(s => s.Name == "Blazam"))
+ using (ServerManager serverManager = new ServerManager())
{
- Site site = serverManager.Sites.Add("Blazam",
- "http",
- InstallationConfiguraion.WebHostConfiguration.ListeningAddress + ":" + InstallationConfiguraion.WebHostConfiguration.HttpPort + ":",
- InstallationConfiguraion.InstallDirPath + @"Blazam\\");
+ Log.Information("IIS Connected");
+ string httpBinding = InstallationConfiguraion.WebHostConfiguration.ListeningAddress + ":" + InstallationConfiguraion.WebHostConfiguration.HttpPort + ":";
+ Site site = serverManager.Sites.FirstOrDefault(s => s.Name == "Blazam");
+ if (site is null)
+ {
+ site = serverManager.Sites.Add("Blazam",
+ "http",
+ httpBinding,
+ InstallationConfiguraion.InstallDirPath + @"Blazam\\");
+ }
+
+ Log.Information("IIS Site {@Site}", site);
+
serverManager.CommitChanges();
+
+ FileSystemService.AddPermission(
+ InstallationConfiguraion.InstallDirPath + @"Blazam\\",
+ "IIS_IUSRS",
+ FileSystemRights.ReadAndExecute
+ );
+ return true;
}
- FileSystemService.AddPermission(
- InstallationConfiguraion.InstallDirPath + @"Blazam\\",
- "IIS_IUSRS",
- FileSystemRights.ReadAndExecute
- );
- return true;
+ }
+ catch ( Exception ex )
+ {
+ Log.Error("Error while creating IIS website. {@Error}", ex);
}
return false;
}
diff --git a/BlazamSetup/Services/InstallationService.cs b/BlazamSetup/Services/InstallationService.cs
index fbf75d1..5714911 100644
--- a/BlazamSetup/Services/InstallationService.cs
+++ b/BlazamSetup/Services/InstallationService.cs
@@ -1,4 +1,6 @@
-using System;
+using Serilog;
+using SQLitePCL;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -14,21 +16,34 @@ internal static class InstallationService
internal static AppEvent OnProgress { get; set; }
internal static AppEvent OnStepTitleChanged { get; set; }
internal static AppEvent OnInstallationFinished { get; set; }
- internal static CancellationTokenSource CancellationTokenSource { get; set; }= new CancellationTokenSource();
+ internal static CancellationTokenSource CancellationTokenSource { get; set; } = new CancellationTokenSource();
- internal static async Task StartInstallationAsync() {
+ internal static async Task StartInstallationAsync()
+ {
+ Log.Information("Installattion Started {@InstallationType} {@InstallDirPath} {@DatabaseConfiguration}", InstallationConfiguraion.InstallationType, InstallationConfiguraion.InstallDirPath, InstallationConfiguraion.DatabaseConfiguration);
+
+ if (!await PreInstallation()) Rollback();
+ if (CancellationTokenSource.IsCancellationRequested) return;
+ if (!await CopySourceFiles(InstallationConfiguraion.InstallDirPath + "\\Blazam\\")) Rollback();
+ if (CancellationTokenSource.IsCancellationRequested) return;
await Task.Run(() =>
{
- PreInstallation();
- CopySourceFiles(InstallationConfiguraion.InstallDirPath + "\\Blazam\\");
- CreateProgramDataDirectory();
+ if (CancellationTokenSource.IsCancellationRequested) return;
+
+ if (!CreateProgramDataDirectory()) Rollback();
+ if (CancellationTokenSource.IsCancellationRequested) return;
+
+
if (InstallationConfiguraion.InstallationType == InstallType.Service && !ServiceManager.IsInstalled)
{
OnStepTitleChanged?.Invoke("Install Services");
OnProgress?.Invoke(0);
- ServiceManager.Install();
+ if (!ServiceManager.Install()) Rollback();
+ if (CancellationTokenSource.IsCancellationRequested) return;
+
+
OnProgress?.Invoke(100);
}
else
@@ -36,37 +51,56 @@ await Task.Run(() =>
OnStepTitleChanged?.Invoke("Configuring IIS");
OnProgress?.Invoke(0);
- IISManager.CreateApplication();
+ if (!IISManager.CreateApplication()) Rollback();
+ if (CancellationTokenSource.IsCancellationRequested) return;
+
OnProgress?.Invoke(100);
}
OnStepTitleChanged?.Invoke("Finishing Installation");
OnProgress?.Invoke(0);
+ if (CancellationTokenSource.IsCancellationRequested) return;
+
//Post install steps
AppSettingsService.Copy();
AppSettingsService.Configure();
- RegistryService.CreateUninstallKey();
RegistryService.SetProductInformation(InstallationConfiguraion.ProductInformation);
OnProgress?.Invoke(100);
OnStepTitleChanged?.Invoke("Installation Finished");
+ Log.Information("Installation Finished Succeessfully");
+
MainWindow.DisableBack();
MainWindow.EnableNext();
});
}
- private static void CreateProgramDataDirectory()
+ private static void Rollback()
{
- string identity = "IIS_IUSRS";
- if (InstallationConfiguraion.InstallationType == InstallType.Service)
- identity = "NT Authority/NetworkService";
-
- Directory.CreateDirectory(InstallationConfiguraion.ProgramDataDir);
- FileSystemService.AddPermission(
- InstallationConfiguraion.ProgramDataDir,
- identity,
- System.Security.AccessControl.FileSystemRights.Write | System.Security.AccessControl.FileSystemRights.Modify | System.Security.AccessControl.FileSystemRights.ReadAndExecute
- );
+ Cancel();
+ }
+
+ private static bool CreateProgramDataDirectory()
+ {
+ try
+ {
+ string identity = "IIS_IUSRS";
+ if (InstallationConfiguraion.InstallationType == InstallType.Service)
+ identity = "NT Authority/NetworkService";
+
+ Directory.CreateDirectory(InstallationConfiguraion.ProgramDataDir);
+ FileSystemService.AddPermission(
+ InstallationConfiguraion.ProgramDataDir,
+ identity,
+ System.Security.AccessControl.FileSystemRights.Write | System.Security.AccessControl.FileSystemRights.Modify | System.Security.AccessControl.FileSystemRights.ReadAndExecute
+ );
+ return true;
+ }catch (Exception ex)
+ {
+ Log.Error("Error creating program data directory: {@Error}", ex);
+
+ }
+ return false;
}
@@ -75,68 +109,83 @@ private static void CreateProgramDataDirectory()
///
///
///
- public static bool CopySourceFiles(string targetDirectory)
+ public static async Task CopySourceFiles(string targetDirectory)
{
- try
+ return await Task.Run(() =>
{
- OnStepTitleChanged?.Invoke("Copy Files");
- bool copyingDownTree = false;
- if (targetDirectory.Contains(DownloadService.SourceDirectory))
+ try
{
- copyingDownTree = true;
- }
- var totalFiles = FileSystemService.GetFileCount(DownloadService.SourceDirectory);
- var fileIndex = 0;
-
- if (Directory.Exists(DownloadService.SetupTempDirectory))
- {
- var directories = Directory.GetDirectories(DownloadService.SourceDirectory, "*", SearchOption.AllDirectories).AsEnumerable();
-
- if (copyingDownTree)
- directories = directories.Where(d => !d.Contains(targetDirectory));
+ OnStepTitleChanged?.Invoke("Copy Files");
+ Log.Information("File copy started");
- //Now Create all of the directories
- foreach (string dirPath in directories)
+ bool copyingDownTree = false;
+ if (targetDirectory.Contains(DownloadService.SourceDirectory))
{
- Directory.CreateDirectory(dirPath.Replace(DownloadService.SourceDirectory, targetDirectory));
+ copyingDownTree = true;
}
- var files = Directory.GetFiles(DownloadService.SourceDirectory, "*.*", SearchOption.AllDirectories).AsEnumerable();
+ var totalFiles = FileSystemService.GetFileCount(DownloadService.SourceDirectory);
+ var fileIndex = 0;
- if (copyingDownTree)
- files = files.Where(f => !f.Contains(targetDirectory));
- //Copy all the files & Replaces any files with the same name
- foreach (string newPath in files)
+ if (Directory.Exists(DownloadService.SetupTempDirectory))
{
- File.Copy(newPath, newPath.Replace(DownloadService.SourceDirectory, targetDirectory), true);
- fileIndex++;
- OnProgress?.Invoke((fileIndex / totalFiles) * 100);
+ var directories = Directory.GetDirectories(DownloadService.SourceDirectory, "*", SearchOption.AllDirectories).AsEnumerable();
+
+ if (copyingDownTree)
+ directories = directories.Where(d => !d.Contains(targetDirectory));
+
+ //Now Create all of the directories
+ foreach (string dirPath in directories)
+ {
+ Log.Information("Creating directory: "+dirPath);
+
+ Directory.CreateDirectory(dirPath.Replace(DownloadService.SourceDirectory, targetDirectory));
+ }
+ var files = Directory.GetFiles(DownloadService.SourceDirectory, "*.*", SearchOption.AllDirectories).AsEnumerable();
+
+ if (copyingDownTree)
+ files = files.Where(f => !f.Contains(targetDirectory));
+ //Copy all the files & Replaces any files with the same name
+ foreach (string path in files)
+ {
+ var newPath = path.Replace(DownloadService.SourceDirectory, targetDirectory);
+ Log.Information("Copying file: " + newPath);
+
+ File.Copy(path, newPath, true);
+ fileIndex++;
+ OnProgress?.Invoke((fileIndex / totalFiles) * 100);
+ }
+ CopySetup(targetDirectory);
+ return true;
+
}
- CopySetup(targetDirectory);
- return true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Error Copying files {@Error}",ex);
+ Console.WriteLine(ex.Message);
}
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- return false;
+ return false;
+ });
+
}
private static void CopySetup(string targetDirectory)
{
var setupPath = Assembly.GetExecutingAssembly().Location;
var destPath = targetDirectory + "setup.exe";
+ Log.Information("Copying file: " + destPath);
+
File.Copy(setupPath, destPath, true);
}
- private static void PreInstallation()
+ private static async Task PreInstallation()
{
OnStepTitleChanged?.Invoke("Extract Files");
- DownloadService.UnpackDownload();
- return;
+ return await DownloadService.UnpackDownload();
+
}
@@ -144,6 +193,8 @@ internal static void Cancel()
{
if (!CancellationTokenSource.IsCancellationRequested)
{
+ Log.Information("Cancelling");
+
CancellationTokenSource.Cancel();
}
}
diff --git a/BlazamSetup/Services/RegistryService.cs b/BlazamSetup/Services/RegistryService.cs
index 7d52808..5fedb1e 100644
--- a/BlazamSetup/Services/RegistryService.cs
+++ b/BlazamSetup/Services/RegistryService.cs
@@ -49,6 +49,8 @@ internal static bool SetProductInformation(ProductInformation productInformation
{
try
{
+ RegistryService.CreateUninstallKey();
+
var key = OpenKey(true);
foreach (var property in typeof(ProductInformation).GetProperties())
{
diff --git a/BlazamSetup/Steps/InstalledActionDialog.xaml b/BlazamSetup/Steps/InstalledActionDialog.xaml
new file mode 100644
index 0000000..58c8123
--- /dev/null
+++ b/BlazamSetup/Steps/InstalledActionDialog.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BlazamSetup/Steps/InstalledActionDialog.xaml.cs b/BlazamSetup/Steps/InstalledActionDialog.xaml.cs
new file mode 100644
index 0000000..87a9070
--- /dev/null
+++ b/BlazamSetup/Steps/InstalledActionDialog.xaml.cs
@@ -0,0 +1,57 @@
+using BlazamSetup.Steps.Uninstall;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace BlazamSetup.Steps
+{
+ ///
+ /// Interaction logic for InstalledActionDialog.xaml
+ ///
+ public partial class InstalledActionDialog : UserControl,IInstallationStep
+ {
+
+ public InstalledActionDialog()
+ {
+ InitializeComponent();
+ }
+
+ private void Update_Checked(object sender, RoutedEventArgs e)
+ {
+ InstallationConfiguraion.InstalledAction = InstalledAction.Update;
+ }
+
+ private void Repair_Checked(object sender, RoutedEventArgs e)
+ {
+ InstallationConfiguraion.InstalledAction = InstalledAction.Repair;
+
+ }
+
+ private void Remove_Checked(object sender, RoutedEventArgs e)
+ {
+
+ InstallationConfiguraion.InstalledAction = InstalledAction.Remove;
+ }
+
+ IInstallationStep IInstallationStep.NextStep()
+ {
+ switch(InstallationConfiguraion.InstalledAction)
+ {
+ case InstalledAction.Remove:
+ default:
+ return new WelcomeUninstall();
+ }
+ }
+ }
+}