154 lines
5.3 KiB
C#
154 lines
5.3 KiB
C#
using Microsoft.VisualBasic.CompilerServices;
|
|
using System.Diagnostics;
|
|
using System.IO.Compression;
|
|
|
|
namespace Pilz.Updating.UpdateInstaller.Lib;
|
|
|
|
public class UpdateInstaller(UpdateInstallerConfig config)
|
|
{
|
|
// E v e n t s
|
|
|
|
public delegate void UpdateInstallerEventHandler(object sender, UpdateInstallerEventArgs e);
|
|
public delegate void UpdateInstallerStepEventHandler(object sender, UpdateInstallerStepEventArgs e);
|
|
public delegate void StatusChangesEventHandler(object sender, UpdateInstallerStatusChangedEventArgs e);
|
|
|
|
public event StatusChangesEventHandler? StatusChanges;
|
|
public event UpdateInstallerStepEventHandler? OnStep;
|
|
|
|
// F i e l d s
|
|
|
|
private string dataPath = string.Empty;
|
|
|
|
// P r o p e r t i e s
|
|
|
|
public UpdateInstallerConfig Configuration { get; private set; } = config;
|
|
|
|
// F e a t u r e s
|
|
|
|
private void ChangeStep(UpdateInstallerStep step, UpdateInstallerStepState state)
|
|
{
|
|
OnStep?.Invoke(this, new UpdateInstallerStepEventArgs(this, step, state));
|
|
}
|
|
|
|
private void ChangeStatus(UpdateInstallerStatus newStatus)
|
|
{
|
|
StatusChanges?.Invoke(this, new UpdateInstallerStatusChangedEventArgs(newStatus));
|
|
}
|
|
|
|
public void StartHostApplication()
|
|
{
|
|
if (!string.IsNullOrEmpty(Conversions.ToString(Configuration.RestartHostApplication)) && File.Exists(Configuration.HostApplicationProcessPath))
|
|
Process.Start(Configuration.HostApplicationProcessPath, Configuration.RestartHostApplicationArguments);
|
|
}
|
|
|
|
public void InstallUpdate()
|
|
{
|
|
ChangeStep(UpdateInstallerStep.Startup, UpdateInstallerStepState.Default);
|
|
|
|
// Extract Package
|
|
ChangeStatus(UpdateInstallerStatus.Extracting);
|
|
ChangeStep(UpdateInstallerStep.ExtractPackage, UpdateInstallerStepState.PreEvent);
|
|
ExtractPackage();
|
|
ChangeStep(UpdateInstallerStep.ExtractPackage, UpdateInstallerStepState.PostEvent);
|
|
|
|
// Install Package
|
|
ChangeStatus(UpdateInstallerStatus.CopyingFiles);
|
|
ChangeStep(UpdateInstallerStep.CopyFiles, UpdateInstallerStepState.PreEvent);
|
|
CopyFiles();
|
|
ChangeStep(UpdateInstallerStep.CopyFiles, UpdateInstallerStepState.PostEvent);
|
|
|
|
// Delete Package
|
|
ChangeStatus(UpdateInstallerStatus.RemovingFiles);
|
|
ChangeStep(UpdateInstallerStep.DeletePackage, UpdateInstallerStepState.PreEvent);
|
|
DeletePackage();
|
|
ChangeStep(UpdateInstallerStep.DeletePackage, UpdateInstallerStepState.PostEvent);
|
|
|
|
// Finish
|
|
ChangeStatus(UpdateInstallerStatus.Done);
|
|
ChangeStep(UpdateInstallerStep.Finish, UpdateInstallerStepState.Default);
|
|
}
|
|
|
|
public void WaitForHostApplication()
|
|
{
|
|
bool forcedKill = false;
|
|
bool enabled = true;
|
|
var stw = new Stopwatch();
|
|
stw.Start();
|
|
Process[] getProcesses() => Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Configuration.HostApplicationProcessPath));
|
|
while (enabled)
|
|
{
|
|
if (getProcesses().Any())
|
|
{
|
|
if (stw.ElapsedMilliseconds >= Configuration.MillisecondsToWaitForHostApplicationToClose)
|
|
{
|
|
if (!forcedKill && Configuration.ForceClosingHostApplication)
|
|
{
|
|
foreach (Process p in getProcesses())
|
|
p.Kill();
|
|
stw.Reset();
|
|
forcedKill = true;
|
|
}
|
|
else
|
|
{
|
|
stw.Stop();
|
|
enabled = false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
enabled = false;
|
|
}
|
|
}
|
|
|
|
private void ExtractPackage()
|
|
{
|
|
string packagePath = Configuration.PackagePath;
|
|
string zipPath = Path.Combine(packagePath, PackageFileNameDefinations.ZIP_PACKAGE_FILENAME);
|
|
dataPath = Path.Combine(packagePath, Path.GetFileNameWithoutExtension(PackageFileNameDefinations.ZIP_PACKAGE_FILENAME));
|
|
var dataPathDir = new DirectoryInfo(dataPath);
|
|
|
|
if (dataPathDir.Exists)
|
|
{
|
|
dataPathDir.Delete(true);
|
|
Task.Delay(100);
|
|
}
|
|
|
|
ZipFile.ExtractToDirectory(zipPath, dataPath);
|
|
}
|
|
|
|
private void CopyFiles()
|
|
{
|
|
var sourceDir = new DirectoryInfo(dataPath);
|
|
var destDir = new DirectoryInfo(Configuration.HostApplicationPath);
|
|
CopyFiles(sourceDir, destDir);
|
|
}
|
|
|
|
private void CopyFiles(DirectoryInfo sourceDir, DirectoryInfo destinationDir)
|
|
{
|
|
if (!destinationDir.Exists)
|
|
destinationDir.Create();
|
|
|
|
foreach (FileInfo sFile in sourceDir.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
|
|
{
|
|
var dFile = new FileInfo(Path.Combine(destinationDir.FullName, sFile.Name));
|
|
try
|
|
{
|
|
sFile.CopyTo(dFile.FullName, true);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
}
|
|
|
|
foreach (DirectoryInfo sDir in sourceDir.EnumerateDirectories("*", SearchOption.TopDirectoryOnly))
|
|
{
|
|
var dDir = destinationDir.CreateSubdirectory(sDir.Name);
|
|
CopyFiles(sDir, dDir);
|
|
}
|
|
}
|
|
|
|
private void DeletePackage()
|
|
{
|
|
Directory.Delete(Configuration.PackagePath, true);
|
|
}
|
|
} |