Exemple #1
0
    /// <summary>
    /// Saves any pending changes to the archive and reloads it
    /// </summary>
    /// <returns>The task</returns>
    public async Task SaveAsync()
    {
        Logger.Info("The archive {0} is being repacked", DisplayName);

        // Run as a load operation
        using (await Archive.LoadOperation.RunAsync())
        {
            // Lock the access to the archive
            using (await Archive.ArchiveLock.LockAsync())
            {
                // Find the selected item path
                string?selectedDirAddr = ExplorerDialogViewModel.SelectedDir == null
                    ? null
                    : ExplorerDialogViewModel.GetDirectoryAddress(ExplorerDialogViewModel.SelectedDir);

                // Run as a task
                await Task.Run(async() =>
                {
                    // Stop file initialization
                    if (ExplorerDialogViewModel.IsInitializingFiles)
                    {
                        ExplorerDialogViewModel.CancelInitializeFiles = true;
                    }

                    Archive.SetDisplayStatus(String.Format(Resources.Archive_RepackingStatus, DisplayName));

                    try
                    {
                        // Get a temporary file path to write to
                        using TempFile tempOutputFile = new(false);

                        // Create the file and get the stream
                        using (ArchiveFileStream outputStream = new(File.Create(tempOutputFile.TempPath), tempOutputFile.TempPath.Name, true))
                        {
                            // Write to the stream
                            Manager.WriteArchive(
                                generator: ArchiveFileGenerator,
                                archive: ArchiveData ?? throw new Exception("Archive data has not been loaded"),
                                outputFileStream: outputStream,
                                files: this.GetAllChildren <ArchiveDirectoryViewModel>(true).
                                SelectMany(x => x.Files).
                                Select(x => x.FileData).
                                ToArray());
                        }

                        // Dispose the archive file stream
                        ArchiveFileStream.Dispose();

                        ArchiveData = null;

                        // If the operation succeeded, replace the archive file with the temporary output
                        Services.File.MoveFile(tempOutputFile.TempPath, FilePath, true);

                        // Re-open the file stream
                        OpenFile();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex, "Repacking archive {0}", DisplayName);

                        await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.Archive_RepackError);

                        // Re-open the file stream if closed
                        if (ArchiveFileStream.SafeFileHandle?.IsClosed != false)
                        {
                            OpenFile();
                        }
                    }
                });

                // Reload the archive
                LoadArchive();

                // Load the previously selected directory if it still exists
                if (selectedDirAddr != null)
                {
                    ExplorerDialogViewModel.LoadDirectory(selectedDirAddr);
                }

                Archive.SetDisplayStatus(String.Empty);
            }
        }
    }