mirror of
https://github.com/k1tbyte/Wand-Enhancer.git
synced 2026-08-30 19:01:23 +00:00
fix(patch): stop the deployed launcher inheriting a read-only flag
This commit is contained in:
@@ -152,6 +152,8 @@ namespace AsarSharp.AsarFileSystem
|
||||
return;
|
||||
}
|
||||
|
||||
// A read-only or hidden archive would fail the swap the same way an overwrite does.
|
||||
Extensions.ClearAttributes(dest);
|
||||
// File.Replace swaps in one step, so dest is never observed missing or half-written.
|
||||
File.Replace(tempPath, dest, null, true);
|
||||
}
|
||||
|
||||
@@ -153,6 +153,28 @@ namespace AsarSharp.Utils
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overwrites <paramref name="destination"/>, clearing attributes on both ends. CopyFile
|
||||
/// carries the source's ReadOnly flag onto the copy and then refuses to overwrite what it
|
||||
/// produced, failing with "Access to the path is denied" - so one read-only source (an exe
|
||||
/// run straight out of a .zip, say) poisons the destination for every later run.
|
||||
/// </summary>
|
||||
public static void CopyOver(string source, string destination)
|
||||
{
|
||||
ClearAttributes(destination);
|
||||
File.Copy(source, destination, true);
|
||||
ClearAttributes(destination);
|
||||
}
|
||||
|
||||
/// <summary>Resets a file to Normal: ReadOnly, Hidden and System all block an overwrite.</summary>
|
||||
public static void ClearAttributes(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.SetAttributes(path, FileAttributes.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CopyDirectory(string sourceDir, string destinationDir)
|
||||
{
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
@@ -160,7 +182,7 @@ namespace AsarSharp.Utils
|
||||
foreach (var file in Directory.GetFiles(sourceDir))
|
||||
{
|
||||
var destFile = Path.Combine(destinationDir, Path.GetFileName(file));
|
||||
File.Copy(file, destFile, true);
|
||||
CopyOver(file, destFile);
|
||||
}
|
||||
|
||||
foreach (var dir in Directory.GetDirectories(sourceDir))
|
||||
|
||||
@@ -22,6 +22,7 @@ The newest entry must match the version in `WandEnhancer/Properties/AssemblyInfo
|
||||
- Fixed the "Buy Pro" banner still showing after a successful patch, and Pro not activating on newer clients.
|
||||
- Fixed the Enhancer closing itself when any button was pressed. #184
|
||||
- A failed patch now puts your original Wand files back instead of leaving a half-patched install behind. Packing also builds the archive beside the old one and swaps it in at the end, so a failure can no longer destroy `app.asar`. #221
|
||||
- Fixed patching and *Restore* both failing with "Access to the path is denied" after the first successful patch. Copying carried the read-only flag from the patcher onto the launcher it installs, and then refused to overwrite what it had written - so running WandEnhancer straight out of the downloaded `.zip`, which Windows marks read-only, broke every later run. #214
|
||||
- Fixed a half-written backup reporting the installation as patched, which blocked patching and restore at the same time.
|
||||
- Fixed invalid ASAR integrity metadata produced from short reads, which could yield an archive the client rejects. #170
|
||||
- Fixed the packer silently dropping files it could not read, for example while Wand was still running.
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace WandEnhancer.Core
|
||||
int copied = 0;
|
||||
foreach (var file in files.Where(WeModInstalls.IsJavaScriptFile).Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
File.Copy(file, GetAvailableScriptPath(destinationDir, Path.GetFileName(file)));
|
||||
AsarSharp.Utils.Extensions.CopyOver(file, GetAvailableScriptPath(destinationDir, Path.GetFileName(file)));
|
||||
copied++;
|
||||
}
|
||||
|
||||
@@ -354,10 +354,10 @@ namespace WandEnhancer.Core
|
||||
|
||||
if (File.Exists(stubPath) && !File.Exists(stubBackup))
|
||||
{
|
||||
File.Copy(stubPath, stubBackup);
|
||||
AsarSharp.Utils.Extensions.CopyOver(stubPath, stubBackup);
|
||||
}
|
||||
|
||||
File.Copy(self, stubPath, true);
|
||||
AsarSharp.Utils.Extensions.CopyOver(self, stubPath);
|
||||
_logger("[ENHANCER] Launcher deployed to root directory", ELogType.Info);
|
||||
}
|
||||
|
||||
@@ -401,12 +401,12 @@ namespace WandEnhancer.Core
|
||||
if (!File.Exists(_backupPath))
|
||||
{
|
||||
_logger("[ENHANCER] Creating backup...", ELogType.Info);
|
||||
File.Copy(_asarPath, _backupPath);
|
||||
AsarSharp.Utils.Extensions.CopyOver(_asarPath, _backupPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger("[ENHANCER] Backup found, restoring pristine app.asar before patching...", ELogType.Info);
|
||||
File.Copy(_backupPath, _asarPath, true);
|
||||
AsarSharp.Utils.Extensions.CopyOver(_backupPath, _asarPath);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(_unpackedBackupPath) && Directory.Exists(_unpackedPath))
|
||||
@@ -503,7 +503,7 @@ namespace WandEnhancer.Core
|
||||
{
|
||||
if (File.Exists(_backupPath))
|
||||
{
|
||||
File.Copy(_backupPath, _asarPath, true);
|
||||
AsarSharp.Utils.Extensions.CopyOver(_backupPath, _asarPath);
|
||||
}
|
||||
|
||||
if (Directory.Exists(_unpackedBackupPath))
|
||||
@@ -533,7 +533,7 @@ namespace WandEnhancer.Core
|
||||
}
|
||||
|
||||
ProcessTerminator.TryKillProcess(_weModConfig.BrandName);
|
||||
File.Copy(_backupPath, _asarPath, true);
|
||||
AsarSharp.Utils.Extensions.CopyOver(_backupPath, _asarPath);
|
||||
|
||||
if (Directory.Exists(_unpackedPath))
|
||||
{
|
||||
@@ -555,14 +555,17 @@ namespace WandEnhancer.Core
|
||||
string stubBackup = stubPath + StubBackupSuffix;
|
||||
if (File.Exists(stubBackup))
|
||||
{
|
||||
File.Copy(stubBackup, stubPath, true);
|
||||
AsarSharp.Utils.Extensions.CopyOver(stubBackup, stubPath);
|
||||
File.Delete(stubBackup);
|
||||
}
|
||||
|
||||
string autoPatchConfig = Path.Combine(squirrelRoot, Constants.AutoPatchConfigFileName);
|
||||
if (File.Exists(autoPatchConfig))
|
||||
foreach (var leftover in new[] { Constants.AutoPatchConfigFileName, LauncherLog.FileName })
|
||||
{
|
||||
File.Delete(autoPatchConfig);
|
||||
string path = Path.Combine(squirrelRoot, leftover);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
File.Delete(_backupPath);
|
||||
|
||||
@@ -58,8 +58,7 @@ namespace WandEnhancer.Core
|
||||
// Electron dies a second or two after a renderer fails, which is past the detach.
|
||||
// Watching that window is the only way the exit code reaches the log.
|
||||
private const int PostDetachWatchMs = 5000;
|
||||
|
||||
/// <summary>Electron's exit code when the ASAR integrity fuse rejects the archive.</summary>
|
||||
|
||||
private const int AsarIntegrityExitCode = -36861;
|
||||
|
||||
private static readonly byte[] Sentinel =
|
||||
@@ -226,7 +225,7 @@ namespace WandEnhancer.Core
|
||||
log?.Invoke($"Wand exited right after detach with code {DescribeCode(exitCode)}.", ELogType.Error);
|
||||
}
|
||||
|
||||
/// <summary>Names the exit and exception codes that actually turn up when Wand will not start.</summary>
|
||||
|
||||
private static string DescribeCode(int code)
|
||||
{
|
||||
switch (code)
|
||||
|
||||
Reference in New Issue
Block a user