Skip to content

Commit d124197

Browse files
committed
Fix installer temp (Closes #1436) (#1449)
1 parent 85593ea commit d124197

1 file changed

Lines changed: 60 additions & 5 deletions

File tree

Daybreak.Installer/Program.cs

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
var daybreakExecutable = OperatingSystem.IsWindows() ? "Daybreak.exe" : "Daybreak";
88
var daybreakProcessName = "Daybreak";
99
var releaseAssetSuffix = OperatingSystem.IsWindows() ? "" : "-linux";
10+
var installerExtension = OperatingSystem.IsWindows() ? ".exe" : "";
11+
12+
// Paths relative to the zip root that should be skipped during extraction
13+
// These are the installer executables that may be currently running
14+
var skipEntriesOnExtract = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
15+
{
16+
$"Installer/Daybreak.Installer{installerExtension}",
17+
$"Installer/Daybreak.Installer.Temp{installerExtension}",
18+
};
1019

1120
static void RenderProgressBar(int currentStep, int totalSteps, int barSize)
1221
{
@@ -23,18 +32,64 @@ static void RenderProgressBar(int currentStep, int totalSteps, int barSize)
2332
Console.Write($"{pctComplete:P0}"); // Display the percentage completed
2433
}
2534

26-
static void CleanWorkingDirectory(string workingDirectory)
35+
static void ExtractZipSkippingEntries(string zipPath, string destinationDirectory, HashSet<string> skipEntries)
36+
{
37+
using var archive = ZipFile.OpenRead(zipPath);
38+
foreach (var entry in archive.Entries)
39+
{
40+
// Normalize entry path separators
41+
var entryPath = entry.FullName.Replace('\\', '/');
42+
43+
// Skip entries in the skip list
44+
if (skipEntries.Any(skip => entryPath.Equals(skip, StringComparison.OrdinalIgnoreCase)))
45+
{
46+
Console.WriteLine($"Skipping: {entry.FullName}");
47+
continue;
48+
}
49+
50+
var destinationPath = Path.GetFullPath(Path.Combine(destinationDirectory, entry.FullName));
51+
52+
// Ensure the destination is within the target directory (security check)
53+
if (!destinationPath.StartsWith(Path.GetFullPath(destinationDirectory), StringComparison.OrdinalIgnoreCase))
54+
{
55+
continue;
56+
}
57+
58+
// If entry is a directory, create it
59+
if (entry.FullName.EndsWith('/') || entry.FullName.EndsWith('\\'))
60+
{
61+
Directory.CreateDirectory(destinationPath);
62+
}
63+
else
64+
{
65+
// Ensure parent directory exists
66+
var parentDir = Path.GetDirectoryName(destinationPath);
67+
if (!string.IsNullOrEmpty(parentDir))
68+
{
69+
Directory.CreateDirectory(parentDir);
70+
}
71+
72+
entry.ExtractToFile(destinationPath, overwrite: true);
73+
}
74+
}
75+
}
76+
77+
static void CleanWorkingDirectory(string workingDirectory, string installerExtension)
2778
{
2879
if (!Directory.Exists(workingDirectory))
2980
{
3081
return;
3182
}
3283

33-
var installerPath = Path.GetFullPath(Path.Combine(workingDirectory, "Installer"));
84+
var installerFolder = Path.GetFullPath(Path.Combine(workingDirectory, "Installer"));
85+
var installerPath = Path.GetFullPath(Path.Combine(installerFolder, $"Daybreak.Installer{installerExtension}"));
86+
var installerTempPath = Path.GetFullPath(Path.Combine(installerFolder, $"Daybreak.Installer.Temp{installerExtension}"));
3487
var optionsPath = Path.GetFullPath(Path.Combine(workingDirectory, "Daybreak.options"));
3588
var preserve = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
3689
{
90+
installerFolder,
3791
installerPath,
92+
installerTempPath,
3893
optionsPath,
3994
};
4095
var preserveExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".tpf" };
@@ -149,7 +204,7 @@ async ValueTask PerformUpdate(string workingDirectory)
149204
Console.WriteLine("Unpacking files...");
150205
try
151206
{
152-
ZipFile.ExtractToDirectory(tempFile, Path.GetFullPath(workingDirectory), true);
207+
ExtractZipSkippingEntries(tempFile, Path.GetFullPath(workingDirectory), skipEntriesOnExtract);
153208
}
154209
catch { }
155210

@@ -224,7 +279,7 @@ or HttpStatusCode.TemporaryRedirect
224279
var tempFile = Path.GetFullPath("tempfile.zip", workingDirectory);
225280

226281
Console.WriteLine($"Cleaning installation directory {workingDirectory}");
227-
CleanWorkingDirectory(workingDirectory);
282+
CleanWorkingDirectory(workingDirectory, installerExtension);
228283

229284
Console.WriteLine($"Downloading Daybreak {version}...");
230285

@@ -272,7 +327,7 @@ or HttpStatusCode.TemporaryRedirect
272327
Console.WriteLine("\nDownload complete. Extracting files...");
273328
try
274329
{
275-
ZipFile.ExtractToDirectory(tempFile, Path.GetFullPath(workingDirectory), true);
330+
ExtractZipSkippingEntries(tempFile, Path.GetFullPath(workingDirectory), skipEntriesOnExtract);
276331
}
277332
catch (Exception e)
278333
{

0 commit comments

Comments
 (0)