diff --git a/desktop/src/main/java/haveno/desktop/app/HavenoApp.java b/desktop/src/main/java/haveno/desktop/app/HavenoApp.java index 06a604dd..3e41aa2f 100644 --- a/desktop/src/main/java/haveno/desktop/app/HavenoApp.java +++ b/desktop/src/main/java/haveno/desktop/app/HavenoApp.java @@ -89,6 +89,8 @@ public class HavenoApp extends Application implements UncaughtExceptionHandler { private static Consumer appLaunchedHandler; @Getter private static Runnable shutDownHandler; + @Setter + private static Runnable onGracefulShutDownHandler; @Setter private Injector injector; @@ -145,6 +147,7 @@ public class HavenoApp extends Application implements UncaughtExceptionHandler { new Thread(() -> { gracefulShutDownHandler.gracefulShutDown(() -> { log.info("App shutdown complete"); + if (onGracefulShutDownHandler != null) onGracefulShutDownHandler.run(); }); }).start(); shutDownRequested = true; diff --git a/desktop/src/main/java/haveno/desktop/main/account/content/backup/BackupView.java b/desktop/src/main/java/haveno/desktop/main/account/content/backup/BackupView.java index 5f2a3ef9..d8d3eea7 100644 --- a/desktop/src/main/java/haveno/desktop/main/account/content/backup/BackupView.java +++ b/desktop/src/main/java/haveno/desktop/main/account/content/backup/BackupView.java @@ -18,6 +18,7 @@ package haveno.desktop.main.account.content.backup; import com.google.inject.Inject; +import haveno.common.UserThread; import haveno.common.config.Config; import haveno.common.file.FileUtil; import haveno.common.persistence.PersistenceManager; @@ -27,6 +28,7 @@ import haveno.core.api.XmrLocalNode; import haveno.core.locale.Res; import haveno.core.user.Preferences; import haveno.core.xmr.wallet.XmrWalletService; +import haveno.desktop.app.HavenoApp; import haveno.desktop.common.view.ActivatableView; import haveno.desktop.common.view.FxmlView; import haveno.desktop.main.overlays.popups.Popup; @@ -40,6 +42,8 @@ import java.io.IOException; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.concurrent.TimeUnit; + import javafx.beans.value.ChangeListener; import javafx.scene.control.Button; import javafx.scene.control.TextField; @@ -125,33 +129,56 @@ public class BackupView extends ActivatableView { openFileOrShowWarning(openLogsButton, logFile); backupNow.setOnAction(event -> { - String backupDirectory = preferences.getBackupDirectory(); - if (backupDirectory != null && backupDirectory.length() > 0) { // We need to flush data to disk - PersistenceManager.flushAllDataToDiskAtBackup(() -> { - try { - // copy data directory to backup directory - String dateString = new SimpleDateFormat("yyyy-MM-dd-HHmmss").format(new Date()); - String destination = Paths.get(backupDirectory, "haveno_backup_" + dateString).toString(); - File destinationFile = new File(destination); - FileUtil.copyDirectory(dataDir, new File(destination)); - - // delete monerod and monero-wallet-rpc binaries from backup so they're reinstalled with permissions - File monerod = new File(destinationFile, XmrLocalNode.MONEROD_NAME); - if (monerod.exists()) monerod.delete(); - File moneroWalletRpc = new File(destinationFile, XmrWalletService.MONERO_WALLET_RPC_NAME); - if (moneroWalletRpc.exists()) moneroWalletRpc.delete(); - new Popup().feedback(Res.get("account.backup.success", destination)).show(); - } catch (IOException e) { - e.printStackTrace(); - log.error(e.getMessage()); - showWrongPathWarningAndReset(e); - } - }); + // windows requires closing wallets for read access + if (Utilities.isWindows()) { + new Popup().information(Res.get("settings.net.needRestart")) + .actionButtonText(Res.get("shared.applyAndShutDown")) + .onAction(() -> { + UserThread.runAfter(() -> { + HavenoApp.setOnGracefulShutDownHandler(() -> doBackup()); + HavenoApp.getShutDownHandler().run(); + }, 500, TimeUnit.MILLISECONDS); + }) + .closeButtonText(Res.get("shared.cancel")) + .onClose(() -> { + // nothing to do + }) + .show(); + } else { + doBackup(); } }); } + private void doBackup() { + log.info("Backing up data directory"); + String backupDirectory = preferences.getBackupDirectory(); + if (backupDirectory != null && backupDirectory.length() > 0) { // We need to flush data to disk + PersistenceManager.flushAllDataToDiskAtBackup(() -> { + try { + + // copy data directory to backup directory + String dateString = new SimpleDateFormat("yyyy-MM-dd-HHmmss").format(new Date()); + String destination = Paths.get(backupDirectory, "haveno_backup_" + dateString).toString(); + File destinationFile = new File(destination); + FileUtil.copyDirectory(dataDir, new File(destination)); + + // delete monerod and monero-wallet-rpc binaries from backup so they're reinstalled with permissions + File monerod = new File(destinationFile, XmrLocalNode.MONEROD_NAME); + if (monerod.exists()) monerod.delete(); + File moneroWalletRpc = new File(destinationFile, XmrWalletService.MONERO_WALLET_RPC_NAME); + if (moneroWalletRpc.exists()) moneroWalletRpc.delete(); + new Popup().feedback(Res.get("account.backup.success", destination)).show(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.getMessage()); + showWrongPathWarningAndReset(e); + } + }); + } + } + private void openFileOrShowWarning(Button button, File dataDir) { button.setOnAction(event -> { try {