2020-04-17 21:45:50 +01:00
|
|
|
// /***************************************************************************
|
|
|
|
|
// Aaru Data Preservation Suite
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Filename : SubdirectoryViewModel.cs
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
//
|
|
|
|
|
// Component : GUI view models.
|
|
|
|
|
//
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// View model and code for the subdirectory contents panel.
|
|
|
|
|
//
|
|
|
|
|
// --[ License ] --------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General public License as
|
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2024-12-19 10:45:18 +00:00
|
|
|
// Copyright © 2011-2025 Natalia Portillo
|
2020-04-17 21:45:50 +01:00
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
2020-04-14 22:05:03 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2022-03-26 16:52:00 +00:00
|
|
|
using System.Threading.Tasks;
|
2025-08-20 21:19:43 +01:00
|
|
|
using System.Windows.Input;
|
2021-09-16 04:42:14 +01:00
|
|
|
using Aaru.CommonTypes.Enums;
|
2022-12-19 11:03:51 +00:00
|
|
|
using Aaru.CommonTypes.Interfaces;
|
2020-04-14 22:05:03 +01:00
|
|
|
using Aaru.CommonTypes.Interop;
|
|
|
|
|
using Aaru.CommonTypes.Structs;
|
|
|
|
|
using Aaru.Core;
|
|
|
|
|
using Aaru.Gui.Models;
|
2025-10-27 11:19:26 +00:00
|
|
|
using Aaru.Helpers;
|
2022-11-19 21:10:41 +00:00
|
|
|
using Aaru.Localization;
|
2025-08-17 05:50:25 +01:00
|
|
|
using Aaru.Logging;
|
2020-04-14 22:05:03 +01:00
|
|
|
using Avalonia.Controls;
|
2025-10-27 11:19:26 +00:00
|
|
|
using Avalonia.Media;
|
2024-05-02 00:50:34 +01:00
|
|
|
using Avalonia.Platform.Storage;
|
2025-08-20 21:19:43 +01:00
|
|
|
using CommunityToolkit.Mvvm.Input;
|
2020-07-22 13:20:25 +01:00
|
|
|
using JetBrains.Annotations;
|
2023-09-26 01:29:07 +01:00
|
|
|
using MsBox.Avalonia;
|
|
|
|
|
using MsBox.Avalonia.Enums;
|
2025-08-20 18:51:05 +01:00
|
|
|
using Sentry;
|
2020-04-14 22:05:03 +01:00
|
|
|
using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
|
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
namespace Aaru.Gui.ViewModels.Panels;
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public sealed class SubdirectoryViewModel
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
readonly SubdirectoryModel _model;
|
|
|
|
|
readonly Window _view;
|
|
|
|
|
|
|
|
|
|
public SubdirectoryViewModel([NotNull] SubdirectoryModel model, Window view)
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2024-05-01 04:39:38 +01:00
|
|
|
Entries = [];
|
|
|
|
|
SelectedEntries = [];
|
2025-08-20 21:19:43 +01:00
|
|
|
ExtractFilesCommand = new AsyncRelayCommand(ExtractFiles);
|
2022-03-06 13:29:38 +00:00
|
|
|
_model = model;
|
|
|
|
|
_view = view;
|
|
|
|
|
|
2022-12-21 20:03:24 +00:00
|
|
|
ErrorNumber errno = model.Plugin.OpenDir(model.Path, out IDirNode node);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(errno != ErrorNumber.NoError)
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2025-08-20 21:19:43 +01:00
|
|
|
_ = MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
|
|
|
|
|
string.Format(UI.Error_0_trying_to_read_1_of_chosen_filesystem,
|
|
|
|
|
errno,
|
|
|
|
|
model.Path),
|
|
|
|
|
ButtonEnum.Ok,
|
|
|
|
|
Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(view);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
while(model.Plugin.ReadDir(node, out string dirent) == ErrorNumber.NoError && dirent is not null)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
errno = model.Plugin.Stat(model.Path + "/" + dirent, out FileEntryInfo stat);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2021-09-16 04:42:14 +01:00
|
|
|
if(errno != ErrorNumber.NoError)
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
AaruLogging.Error(string.Format(UI.Error_0_trying_to_get_information_about_filesystem_entry_named_1,
|
|
|
|
|
errno,
|
|
|
|
|
dirent));
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
continue;
|
2020-04-14 22:05:03 +01:00
|
|
|
}
|
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(stat.Attributes.HasFlag(FileAttributes.Directory) && !model.Listed)
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
model.Subdirectories.Add(new SubdirectoryModel
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
Name = dirent,
|
|
|
|
|
Path = model.Path + "/" + dirent,
|
|
|
|
|
Plugin = model.Plugin
|
|
|
|
|
});
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Entries.Add(new FileModel
|
|
|
|
|
{
|
|
|
|
|
Name = dirent,
|
2025-10-27 11:19:26 +00:00
|
|
|
Stat = stat,
|
|
|
|
|
Color =
|
2025-11-21 01:13:28 +00:00
|
|
|
new SolidColorBrush(Color.Parse(DirColorsParser.Instance.ExtensionColors
|
|
|
|
|
.TryGetValue(Path.GetExtension(dirent),
|
|
|
|
|
out string hex)
|
|
|
|
|
? hex
|
|
|
|
|
: DirColorsParser.Instance.NormalColor))
|
2022-03-06 13:29:38 +00:00
|
|
|
});
|
|
|
|
|
}
|
2022-12-21 20:03:24 +00:00
|
|
|
|
|
|
|
|
model.Plugin.CloseDir(node);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public ObservableCollection<FileModel> Entries { get; }
|
|
|
|
|
public List<FileModel> SelectedEntries { get; }
|
2025-08-20 21:19:43 +01:00
|
|
|
public ICommand ExtractFilesCommand { get; }
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2025-08-20 21:19:43 +01:00
|
|
|
async Task ExtractFiles()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(SelectedEntries.Count == 0) return;
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
IReadOnlyList<IStorageFolder> result =
|
|
|
|
|
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
|
|
|
|
{
|
|
|
|
|
Title = UI.Dialog_Choose_destination_folder,
|
|
|
|
|
AllowMultiple = false
|
|
|
|
|
});
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
if(result.Count != 1) return;
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Statistics.AddCommand("extract-files");
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2024-05-02 00:50:34 +01:00
|
|
|
string folder = result[0].Path.AbsolutePath;
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(FileModel file in SelectedEntries)
|
|
|
|
|
{
|
|
|
|
|
string filename = file.Name;
|
|
|
|
|
|
2022-11-13 19:16:14 +00:00
|
|
|
ButtonResult mboxResult;
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(DetectOS.IsWindows)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2023-10-04 08:13:57 +01:00
|
|
|
if(filename.Contains('<') ||
|
|
|
|
|
filename.Contains('>') ||
|
|
|
|
|
filename.Contains(':') ||
|
|
|
|
|
filename.Contains('\\') ||
|
|
|
|
|
filename.Contains('/') ||
|
|
|
|
|
filename.Contains('|') ||
|
|
|
|
|
filename.Contains('?') ||
|
|
|
|
|
filename.Contains('*') ||
|
|
|
|
|
filename.Any(c => c < 32) ||
|
|
|
|
|
filename.Equals("CON", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("PRN", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("AUX", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM1", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM2", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM3", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM4", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM5", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM6", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM7", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM8", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("COM9", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT1", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT2", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT3", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT4", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT5", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT6", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT7", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT8", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Equals("LPT9", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.Last() == '.' ||
|
|
|
|
|
filename.Last() == ' ')
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
char[] chars;
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
if(filename.Last() == '.' || filename.Last() == ' ')
|
2022-03-06 13:29:38 +00:00
|
|
|
chars = new char[filename.Length - 1];
|
|
|
|
|
else
|
|
|
|
|
chars = new char[filename.Length];
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2025-10-25 12:53:52 +01:00
|
|
|
for(var ci = 0; ci < chars.Length; ci++)
|
2023-10-03 23:27:57 +01:00
|
|
|
{
|
2024-05-01 17:18:37 +01:00
|
|
|
chars[ci] = filename[ci] switch
|
|
|
|
|
{
|
|
|
|
|
'<'
|
|
|
|
|
or '>'
|
|
|
|
|
or ':'
|
|
|
|
|
or '\\'
|
|
|
|
|
or '/'
|
|
|
|
|
or '|'
|
|
|
|
|
or '?'
|
|
|
|
|
or '*'
|
|
|
|
|
or '\u0000'
|
|
|
|
|
or '\u0001'
|
|
|
|
|
or '\u0002'
|
|
|
|
|
or '\u0003'
|
|
|
|
|
or '\u0004'
|
|
|
|
|
or '\u0005'
|
|
|
|
|
or '\u0006'
|
|
|
|
|
or '\u0007'
|
|
|
|
|
or '\u0008'
|
|
|
|
|
or '\u0009'
|
|
|
|
|
or '\u000A'
|
|
|
|
|
or '\u000B'
|
|
|
|
|
or '\u000C'
|
|
|
|
|
or '\u000D'
|
|
|
|
|
or '\u000E'
|
|
|
|
|
or '\u000F'
|
|
|
|
|
or '\u0010'
|
|
|
|
|
or '\u0011'
|
|
|
|
|
or '\u0012'
|
|
|
|
|
or '\u0013'
|
|
|
|
|
or '\u0014'
|
|
|
|
|
or '\u0015'
|
|
|
|
|
or '\u0016'
|
|
|
|
|
or '\u0017'
|
|
|
|
|
or '\u0018'
|
|
|
|
|
or '\u0019'
|
|
|
|
|
or '\u001A'
|
|
|
|
|
or '\u001B'
|
|
|
|
|
or '\u001C'
|
|
|
|
|
or '\u001D'
|
|
|
|
|
or '\u001E'
|
|
|
|
|
or '\u001F' => '_',
|
|
|
|
|
_ => filename[ci]
|
|
|
|
|
};
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(filename.StartsWith("CON", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.StartsWith("PRN", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.StartsWith("AUX", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.StartsWith("COM", StringComparison.InvariantCultureIgnoreCase) ||
|
|
|
|
|
filename.StartsWith("LPT", StringComparison.InvariantCultureIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
chars[0] = '_';
|
|
|
|
|
chars[1] = '_';
|
|
|
|
|
chars[2] = '_';
|
2020-04-14 22:05:03 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string corrected = new(chars);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2023-09-26 01:29:07 +01:00
|
|
|
mboxResult = await MessageBoxManager.GetMessageBoxStandard(UI.Unsupported_filename,
|
2024-05-01 04:05:22 +01:00
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Filename_0_not_supported_want_to_rename_to_1,
|
|
|
|
|
filename,
|
|
|
|
|
corrected),
|
|
|
|
|
ButtonEnum.YesNoCancel,
|
|
|
|
|
Icon.Warning)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-11-13 19:38:03 +00:00
|
|
|
switch(mboxResult)
|
|
|
|
|
{
|
2023-10-03 23:27:57 +01:00
|
|
|
case ButtonResult.Cancel:
|
|
|
|
|
return;
|
|
|
|
|
case ButtonResult.No:
|
|
|
|
|
continue;
|
2022-11-13 19:38:03 +00:00
|
|
|
default:
|
|
|
|
|
filename = corrected;
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-11-13 19:38:03 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
}
|
2023-10-03 23:27:57 +01:00
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string outputPath = Path.Combine(folder, filename);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(File.Exists(outputPath))
|
|
|
|
|
{
|
2023-09-26 01:29:07 +01:00
|
|
|
mboxResult = await MessageBoxManager.GetMessageBoxStandard(UI.Existing_file,
|
2024-05-01 04:05:22 +01:00
|
|
|
string
|
|
|
|
|
.Format(UI.File_named_0_exists_overwrite_Q,
|
2023-10-04 17:34:40 +01:00
|
|
|
filename),
|
2024-05-01 04:05:22 +01:00
|
|
|
ButtonEnum.YesNoCancel,
|
|
|
|
|
Icon.Warning)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-11-13 19:38:03 +00:00
|
|
|
switch(mboxResult)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2023-10-03 23:27:57 +01:00
|
|
|
case ButtonResult.Cancel:
|
|
|
|
|
return;
|
|
|
|
|
case ButtonResult.No:
|
|
|
|
|
continue;
|
2022-11-13 19:38:03 +00:00
|
|
|
default:
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
File.Delete(outputPath);
|
|
|
|
|
}
|
|
|
|
|
catch(IOException)
|
|
|
|
|
{
|
2023-09-26 01:29:07 +01:00
|
|
|
mboxResult = await MessageBoxManager.GetMessageBoxStandard(UI.Cannot_delete,
|
2023-10-04 17:34:40 +01:00
|
|
|
UI.Could_note_delete_existe_file_continue_Q,
|
|
|
|
|
ButtonEnum.YesNo,
|
2024-05-01 04:05:22 +01:00
|
|
|
Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2022-11-13 19:38:03 +00:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(mboxResult == ButtonResult.No) return;
|
2022-11-13 19:38:03 +00:00
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-11-13 19:38:03 +00:00
|
|
|
break;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
try
|
|
|
|
|
{
|
2025-10-25 12:53:52 +01:00
|
|
|
var outBuf = new byte[file.Stat.Length];
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-12-19 11:03:51 +00:00
|
|
|
ErrorNumber error = _model.Plugin.OpenFile(_model.Path + "/" + file.Name, out IFileNode fileNode);
|
|
|
|
|
|
|
|
|
|
if(error == ErrorNumber.NoError)
|
|
|
|
|
{
|
|
|
|
|
error = _model.Plugin.ReadFile(fileNode, file.Stat.Length, outBuf, out _);
|
|
|
|
|
_model.Plugin.CloseFile(fileNode);
|
|
|
|
|
}
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(error != ErrorNumber.NoError)
|
2020-04-14 22:05:03 +01:00
|
|
|
{
|
2023-09-26 01:29:07 +01:00
|
|
|
mboxResult = await MessageBoxManager.GetMessageBoxStandard(UI.Error_reading_file,
|
2024-05-01 04:05:22 +01:00
|
|
|
string
|
|
|
|
|
.Format(UI
|
|
|
|
|
.Error_0_reading_file_continue_Q,
|
|
|
|
|
error),
|
|
|
|
|
ButtonEnum.YesNo,
|
|
|
|
|
Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2020-04-14 22:05:03 +01:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(mboxResult == ButtonResult.No) return;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fs = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None);
|
|
|
|
|
|
|
|
|
|
fs.Write(outBuf, 0, outBuf.Length);
|
|
|
|
|
fs.Close();
|
|
|
|
|
var fi = new FileInfo(outputPath);
|
2025-08-20 18:51:05 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
try
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(file.Stat.CreationTimeUtc.HasValue) fi.CreationTimeUtc = file.Stat.CreationTimeUtc.Value;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2025-08-20 18:51:05 +01:00
|
|
|
catch(Exception ex)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
SentrySdk.CaptureException(ex);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(file.Stat.LastWriteTimeUtc.HasValue) fi.LastWriteTimeUtc = file.Stat.LastWriteTimeUtc.Value;
|
2020-04-14 22:05:03 +01:00
|
|
|
}
|
2025-08-20 18:51:05 +01:00
|
|
|
catch(Exception ex)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
SentrySdk.CaptureException(ex);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-05-01 04:05:22 +01:00
|
|
|
if(file.Stat.AccessTimeUtc.HasValue) fi.LastAccessTimeUtc = file.Stat.AccessTimeUtc.Value;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2025-08-20 18:51:05 +01:00
|
|
|
catch(Exception ex)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2025-08-20 18:51:05 +01:00
|
|
|
SentrySdk.CaptureException(ex);
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(IOException)
|
|
|
|
|
{
|
2023-09-26 01:29:07 +01:00
|
|
|
mboxResult = await MessageBoxManager.GetMessageBoxStandard(UI.Cannot_create_file,
|
2024-05-01 04:05:22 +01:00
|
|
|
UI
|
|
|
|
|
.Could_not_create_destination_file_continue_Q,
|
|
|
|
|
ButtonEnum.YesNo,
|
|
|
|
|
Icon.Error)
|
|
|
|
|
.ShowWindowDialogAsync(_view);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
if(mboxResult == ButtonResult.No) return;
|
2020-04-14 22:05:03 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|