diff --git a/I18N Commander/Processor/Generators/DotnetBigFile.cs b/I18N Commander/Processor/Generators/DotnetBigFile.cs index 15625fc..7b20abd 100644 --- a/I18N Commander/Processor/Generators/DotnetBigFile.cs +++ b/I18N Commander/Processor/Generators/DotnetBigFile.cs @@ -8,17 +8,27 @@ public class DotnetBigFile : IGenerator private static readonly List CULTURE_CODES = new(); private static int DEFAULT_CULTURE_INDEX = -1; - public async Task GenerateAsync() + public async Task> GenerateAsync() { const string filename = "I18N.cs"; var destPath = await AppSettings.GetGeneratorDotnetDestinationPath(); destPath = Environment.ExpandEnvironmentVariables(destPath); + long destBytesWritten = 0; var pathFinal = Path.Join(destPath, filename); var pathTemp = Path.Join(destPath, filename + ".gen"); - if(File.Exists(pathTemp)) - File.Delete(pathTemp); + var issueFinal = string.Empty; + + try + { + if(File.Exists(pathTemp)) + File.Delete(pathTemp); + } + catch (IOException e) + { + return new ProcessorResult(0, false, $"Cannot delete the temporary file: '{e.Message}'. Hint: Is the ransomware protection enabled in your Windows system? If so, please make sure that the I18N Commander has write permission."); + } CULTURE_CODES.Clear(); var cultures = await AppSettings.GetCultureInfos(); @@ -49,16 +59,40 @@ public class DotnetBigFile : IGenerator await this.TransformSection(writer, indention, section); }); } + catch (IOException e) + { + // Happens, e.g. when the ransomware protection on Windows is active and + // the I18N commander is not on the exclusion list. + return new ProcessorResult(0, false, $"Cannot write the generator's result file: '{e.Message}'. Hint: Is the ransomware protection enabled in your Windows system? If so, please make sure that the I18N Commander has write permission."); + } finally { - if(new FileInfo(pathTemp).Length > 0) + if (File.Exists(pathTemp)) { - if(File.Exists(pathFinal)) - File.Delete(pathFinal); - - File.Move(pathTemp, pathFinal); + destBytesWritten = new FileInfo(pathTemp).Length; + if (destBytesWritten > 0) + { + try + { + if (File.Exists(pathFinal)) + File.Delete(pathFinal); + + File.Move(pathTemp, pathFinal); + } + catch (IOException e) + { + // Happens when the file is still in use by the compiler, the IDE, etc. + // Depends on the timing, this happens sometimes. We ignore it, though. + issueFinal = e.Message; + } + } } } + + if(string.IsNullOrWhiteSpace(issueFinal)) + return new ProcessorResult(destBytesWritten, true, string.Empty); + else + return new ProcessorResult(0, false, $"Cannot move the generator's result file to the destination: '{issueFinal}'. Hint: Is the ransomware protection enabled in your Windows system? If so, please make sure that the I18N Commander has write permission."); } private string AddIndention(int indention) => new string(' ', indention * 3); diff --git a/I18N Commander/Processor/Generators/Generator.cs b/I18N Commander/Processor/Generators/Generator.cs index 045911a..29ed588 100644 --- a/I18N Commander/Processor/Generators/Generator.cs +++ b/I18N Commander/Processor/Generators/Generator.cs @@ -12,15 +12,30 @@ public static class Generator _ => VOID_GENERATOR, }; - public static async Task TriggerAllAsync() + public static async Task> TriggerAllAsync() { var dotnetEnabled = await AppSettings.GetGeneratorDotnetEnabled(); var godotEnabled = await AppSettings.GetGeneratorGodotEnabled(); + long bytesWritten = 0; if (dotnetEnabled) - await Generator.Get(Type.DOTNET).GenerateAsync(); - + { + var result = await Generator.Get(Type.DOTNET).GenerateAsync(); + if(!result.Successful) + return result; + + bytesWritten += result.Result; + } + if(godotEnabled) - await Generator.Get(Type.GODOT).GenerateAsync(); + { + var result = await Generator.Get(Type.GODOT).GenerateAsync(); + if(!result.Successful) + return result; + + bytesWritten += result.Result; + } + + return new ProcessorResult(bytesWritten); } } \ No newline at end of file diff --git a/I18N Commander/Processor/Generators/IGenerator.cs b/I18N Commander/Processor/Generators/IGenerator.cs index 14f87cc..39ded9e 100644 --- a/I18N Commander/Processor/Generators/IGenerator.cs +++ b/I18N Commander/Processor/Generators/IGenerator.cs @@ -2,5 +2,5 @@ public interface IGenerator { - public Task GenerateAsync(); + public Task> GenerateAsync(); } \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/SectionTree.cs b/I18N Commander/UI WinForms/Components/SectionTree.cs index d0a8e99..878fe74 100644 --- a/I18N Commander/UI WinForms/Components/SectionTree.cs +++ b/I18N Commander/UI WinForms/Components/SectionTree.cs @@ -331,7 +331,9 @@ public partial class SectionTree : UserControl } this.buttonGenerate.Enabled = false; - await Generator.TriggerAllAsync(); + var result = await Generator.TriggerAllAsync(); + result.ProcessError(); + this.buttonGenerate.Enabled = true; } } \ No newline at end of file diff --git a/I18N Commander/UI WinForms/ExtensionsError.cs b/I18N Commander/UI WinForms/ExtensionsError.cs index e21b8ee..f265e66 100644 --- a/I18N Commander/UI WinForms/ExtensionsError.cs +++ b/I18N Commander/UI WinForms/ExtensionsError.cs @@ -6,7 +6,8 @@ public static class ExtensionsError { public static void ProcessError(this ProcessorResult result) { - if (result.Successful) return; + if (result.Successful) + return; MessageBox.Show(result.ErrorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }