Skip to content

Commit

Permalink
Disable readonly property before deleting files (#613)
Browse files Browse the repository at this point in the history
  • Loading branch information
SadPencil authored Jan 3, 2025
1 parent b4e0589 commit 74768c8
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 18 deletions.
5 changes: 5 additions & 0 deletions ClientUpdater/CustomComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ namespace ClientUpdater;
using System.Net.Http.Handlers;
using System.Threading;
using System.Threading.Tasks;

using ClientUpdater.Compression;

using Rampastring.Tools;

/// <summary>
Expand Down Expand Up @@ -377,7 +379,10 @@ private void CleanUpAfterDownload()
foreach (string filename in filesToCleanup)
{
if (File.Exists(filename))
{
new FileInfo(filename).IsReadOnly = false;
File.Delete(filename);
}
}
}
catch (Exception)
Expand Down
83 changes: 67 additions & 16 deletions ClientUpdater/Updater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ namespace ClientUpdater;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using ClientUpdater.Compression;

using Rampastring.Tools;

public static class Updater
Expand Down Expand Up @@ -429,6 +431,8 @@ internal static void DeleteFileAndWait(string filepath, int timeout = 10000)
{
mre.Set();
};
if (fileInfo.Exists)
fileInfo.IsReadOnly = false;
fileInfo.Delete();
mre.Wait(timeout);
}
Expand Down Expand Up @@ -613,15 +617,15 @@ private static async Task DoVersionCheckAsync()

UpdateUserAgent(SharedHttpClient);

FileInfo downloadFile = SafePath.GetFile(GamePath, FormattableString.Invariant($"{VERSION_FILE}_u"));
FileInfo versionFile = SafePath.GetFile(GamePath, FormattableString.Invariant($"{VERSION_FILE}_u"));

while (currentUpdateMirrorIndex < updateMirrors.Count)
{
try
{
Logger.Log("Updater: Trying to connect to update mirror " + updateMirrors[currentUpdateMirrorIndex].URL);

FileStream fileStream = new FileStream(downloadFile.FullName, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous);
FileStream fileStream = new FileStream(versionFile.FullName, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous);

using (fileStream)
{
Expand Down Expand Up @@ -650,7 +654,7 @@ private static async Task DoVersionCheckAsync()
}

Logger.Log("Updater: Downloaded version information.");
var version = new IniFile(downloadFile.FullName);
var version = new IniFile(versionFile.FullName);
string versionString = version.GetStringValue("DTA", "Version", string.Empty);
string updaterVersionString = version.GetStringValue("DTA", "UpdaterVersion", "N/A");
string manualDownloadURLString = version.GetStringValue("DTA", "ManualDownloadURL", string.Empty);
Expand Down Expand Up @@ -722,7 +726,7 @@ private static async Task DoVersionCheckAsync()
if (versionString == GameVersion)
{
VersionState = VersionState.UPTODATE;
downloadFile.Delete();
versionFile.Delete();
DoFileIdentifiersUpdatedEvent();

if (AreCustomComponentsOutdated())
Expand All @@ -736,7 +740,7 @@ private static async Task DoVersionCheckAsync()
VersionState = VersionState.OUTDATED;
ManualUpdateRequired = true;
ManualDownloadURL = manualDownloadURLString;
downloadFile.Delete();
versionFile.Delete();
DoFileIdentifiersUpdatedEvent();
}
else
Expand Down Expand Up @@ -779,7 +783,7 @@ private static async ValueTask ExecuteAfterUpdateScriptAsync()
try
{
string downloadFile = SafePath.CombineFilePath(GamePath, "updateexec");

FileStream fileStream = new FileStream(downloadFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous);

using (fileStream)
Expand Down Expand Up @@ -811,7 +815,7 @@ private static async ValueTask<bool> ExecutePreUpdateScriptAsync()
try
{
string downloadFile = SafePath.CombineFilePath(GamePath, "preupdateexec");

FileStream fileStream = new FileStream(downloadFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous);

using (fileStream)
Expand Down Expand Up @@ -851,7 +855,13 @@ private static void ExecuteScript(string fileName)

try
{
SafePath.DeleteFileIfExists(GamePath, key);
FileInfo fileInfo = SafePath.GetFile(GamePath, key);

if (fileInfo.Exists)
{
fileInfo.IsReadOnly = false;
fileInfo.Delete();
}
}
catch (Exception ex)
{
Expand All @@ -869,10 +879,30 @@ private static void ExecuteScript(string fileName)
{
Logger.Log("Updater: " + fileName + ": Renaming file '" + key + "' to '" + newFilename + "'");

FileInfo file = SafePath.GetFile(GamePath, key);
FileInfo srcFile = SafePath.GetFile(GamePath, key);

if (srcFile.Exists)
{
bool isSrcReadOnly = srcFile.IsReadOnly;
srcFile.IsReadOnly = false;

{
FileInfo destFile = SafePath.GetFile(GamePath, newFilename);
if (destFile.Exists)
{
destFile.IsReadOnly = false;
destFile.Delete();
}
}

srcFile.MoveTo(SafePath.CombineFilePath(GamePath, newFilename));

if (file.Exists)
file.MoveTo(SafePath.CombineFilePath(GamePath, newFilename));
if (isSrcReadOnly)
{
FileInfo destFile = SafePath.GetFile(GamePath, newFilename);
destFile.IsReadOnly = true;
}
}
}
catch (Exception ex)
{
Expand All @@ -890,10 +920,10 @@ private static void ExecuteScript(string fileName)
{
Logger.Log("Updater: " + fileName + ": Renaming directory '" + key + "' to '" + newDirectoryName + "'");

DirectoryInfo directory = SafePath.GetDirectory(GamePath, key);
DirectoryInfo srcDirectory = SafePath.GetDirectory(GamePath, key);

if (directory.Exists)
directory.MoveTo(SafePath.CombineDirectoryPath(GamePath, newDirectoryName));
if (srcDirectory.Exists)
srcDirectory.MoveTo(SafePath.CombineDirectoryPath(GamePath, newDirectoryName));
}
catch (Exception ex)
{
Expand Down Expand Up @@ -928,18 +958,29 @@ private static void ExecuteScript(string fileName)
FileInfo[] files = gameDirectory.GetFiles();
foreach (FileInfo file in files)
{
bool isSrcReadOnly = file.IsReadOnly;
file.IsReadOnly = false;

FileInfo fileToMergeInto = SafePath.GetFile(directoryToMergeInto.FullName, file.Name);
if (fileToMergeInto.Exists)
{
Logger.Log("Updater: " + fileName + ": Destination file '" + directoryNameToMergeInto + "/" + file.Name +
"' exists, removing original source file " + directoryName + "/" + file.Name);
fileToMergeInto.Delete();

// Note: Previously, the incorrect file was deleted as of commit fc939a06ff978b51daa6563eaa15a28cf48319ec.

// Remove the original source file
file.Delete();
}
else
{
Logger.Log("Updater: " + fileName + ": Destination file '" + directoryNameToMergeInto + "/" + file.Name +
"' does not exist, moving original source file " + directoryName + "/" + file.Name);
file.MoveTo(fileToMergeInto.FullName);

// Resume the read-only property
fileToMergeInto.Refresh();
fileToMergeInto.IsReadOnly = isSrcReadOnly;
}
}
}
Expand All @@ -959,7 +1000,17 @@ private static void ExecuteScript(string fileName)
{
Logger.Log("Updater: " + fileName + ": Deleting directory '" + key + "'");

SafePath.DeleteDirectoryIfExists(true, GamePath, key);
DirectoryInfo directoryInfo = SafePath.GetDirectory(GamePath, key);
if (directoryInfo.Exists)
{
// Unset read-only attribute from all files in the directory.
foreach (FileInfo file in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
{
file.IsReadOnly = false;
}

directoryInfo.Delete(true);
}
}
catch (Exception ex)
{
Expand Down
1 change: 1 addition & 0 deletions DTAConfig/OptionPanels/ComponentsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ private void Btn_LeftClick(object sender, EventArgs e)
{
if (cc.LocalIdentifier == cc.RemoteIdentifier)
{
localFileInfo.IsReadOnly = false;
localFileInfo.Delete();
btn.Text = "Install".L10N("Client:DTAConfig:Install") + $" ({GetSizeString(cc.RemoteSize)})";
return;
Expand Down
9 changes: 7 additions & 2 deletions DTAConfig/OptionPanels/DisplayOptionsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ public override bool Save()
IniSettings.Translation.Value = (string)ddTranslation.SelectedItem.Tag;

// copy translation files to the game directory
ClientConfiguration.Instance.TranslationGameFiles.AsParallel().ForAll(tgf =>
ClientConfiguration.Instance.TranslationGameFiles.AsParallel().ForAll(tgf =>
{
string sourcePath = SafePath.CombineFilePath(IniSettings.TranslationFolderPath, tgf.Source);
string targetPath = SafePath.CombineFilePath(ProgramConstants.GamePath, tgf.Target);
Expand Down Expand Up @@ -886,7 +886,12 @@ public override bool Save()
{
string languageDllDestinationPath = SafePath.CombineFilePath(ProgramConstants.GamePath, "Language.dll");

SafePath.DeleteFileIfExists(languageDllDestinationPath);
FileInfo fileInfo = SafePath.GetFile(languageDllDestinationPath);
if (fileInfo.Exists)
{
fileInfo.IsReadOnly = false;
fileInfo.Delete();
}

if (ingameRes.Width >= 1024 && ingameRes.Height >= 720)
System.IO.File.Copy(SafePath.CombineFilePath(ProgramConstants.GamePath, "Resources", "language_1024x720.dll"), languageDllDestinationPath);
Expand Down

0 comments on commit 74768c8

Please sign in to comment.