diff --git a/main/ui/package/windows/Cryptomator-Portable-setup-icon.bmp b/main/ui/package/windows/Cryptomator-Portable-setup-icon.bmp
new file mode 100644
index 000000000..807170bc6
Binary files /dev/null and b/main/ui/package/windows/Cryptomator-Portable-setup-icon.bmp differ
diff --git a/main/ui/package/windows/Cryptomator-Portable.ico b/main/ui/package/windows/Cryptomator-Portable.ico
new file mode 100644
index 000000000..1ce3cc9bb
Binary files /dev/null and b/main/ui/package/windows/Cryptomator-Portable.ico differ
diff --git a/main/ui/package/windows/Cryptomator-Portable.iss b/main/ui/package/windows/Cryptomator-Portable.iss
new file mode 100644
index 000000000..bbbee3d77
--- /dev/null
+++ b/main/ui/package/windows/Cryptomator-Portable.iss
@@ -0,0 +1,74 @@
+;This file will be executed next to the application bundle image
+;I.e. current directory will contain folder APPLICATION_NAME with application files
+[Setup]
+AppId={{PRODUCT_APP_IDENTIFIER}}
+AppName=APPLICATION_NAME
+AppVersion=APPLICATION_VERSION
+AppVerName=APPLICATION_NAME APPLICATION_VERSION
+AppPublisher=APPLICATION_VENDOR
+AppComments=APPLICATION_COMMENTS
+AppCopyright=APPLICATION_COPYRIGHT
+AppPublisherURL=https://cryptomator.org/
+;AppSupportURL=http://java.com/
+;AppUpdatesURL=http://java.com/
+DefaultDirName=APPLICATION_INSTALL_ROOT\APPLICATION_NAME
+DisableStartupPrompt=Yes
+DisableDirPage=No
+DisableProgramGroupPage=Yes
+DisableReadyPage=Yes
+DisableFinishedPage=No
+DisableWelcomePage=Yes
+DefaultGroupName=APPLICATION_GROUP
+;Optional License
+LicenseFile=APPLICATION_LICENSE_FILE
+;WinXP or above
+MinVersion=0,5.1
+OutputBaseFilename=INSTALLER_FILE_NAME
+Compression=lzma
+SolidCompression=yes
+PrivilegesRequired=admin
+SetupIconFile=APPLICATION_NAME\APPLICATION_NAME.ico
+UninstallDisplayIcon={app}\APPLICATION_NAME.ico
+UninstallDisplayName=APPLICATION_NAME
+WizardImageStretch=No
+WizardSmallImageFile=Cryptomator-Portable-setup-icon.bmp
+WizardImageBackColor=$ffffff
+ArchitecturesInstallIn64BitMode=ARCHITECTURE_BIT_MODE
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Files]
+Source: "APPLICATION_NAME\APPLICATION_NAME.exe"; DestDir: "{app}"; Flags: ignoreversion
+Source: "APPLICATION_NAME\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+
+[Icons]
+Name: "{group}\APPLICATION_NAME"; Filename: "{app}\APPLICATION_NAME.exe"; IconFilename: "{app}\APPLICATION_NAME.ico"; Check: APPLICATION_MENU_SHORTCUT()
+Name: "{commondesktop}\APPLICATION_NAME"; Filename: "{app}\APPLICATION_NAME.exe"; IconFilename: "{app}\APPLICATION_NAME.ico"; Check: APPLICATION_DESKTOP_SHORTCUT()
+
+[Run]
+Filename: "{app}\RUN_FILENAME.exe"; Description: "{cm:LaunchProgram,APPLICATION_NAME}"; Flags: nowait postinstall skipifsilent; Check: APPLICATION_NOT_SERVICE()
+Filename: "{app}\RUN_FILENAME.exe"; Parameters: "-install -svcName ""APPLICATION_NAME"" -svcDesc ""APPLICATION_DESCRIPTION"" -mainExe ""APPLICATION_LAUNCHER_FILENAME"" START_ON_INSTALL RUN_AT_STARTUP"; Check: APPLICATION_SERVICE()
+
+[UninstallRun]
+Filename: "{app}\RUN_FILENAME.exe "; Parameters: "-uninstall -svcName APPLICATION_NAME STOP_ON_UNINSTALL"; Check: APPLICATION_SERVICE()
+
+[Code]
+function returnTrue(): Boolean;
+begin
+ Result := True;
+end;
+
+function returnFalse(): Boolean;
+begin
+ Result := False;
+end;
+
+function InitializeSetup(): Boolean;
+begin
+// Possible future improvements:
+// if version less or same => just launch app
+// if upgrade => check if same app is running and wait for it to exit
+// Add pack200/unpack200 support?
+ Result := True;
+end;
diff --git a/main/ui/pom.xml b/main/ui/pom.xml
index 4155fdcb1..7a5ed1117 100644
--- a/main/ui/pom.xml
+++ b/main/ui/pom.xml
@@ -120,4 +120,50 @@
+
+
+
+ portable-win
+
+
+ Windows
+
+
+
+
+
+ maven-antrun-plugin
+ 1.7
+
+
+ create-portable-deployment-bundle
+ install
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java b/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java
index b1c5552ae..bc60720d1 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java
@@ -50,14 +50,22 @@ public class SettingsProvider implements Provider {
this.deferredCloser = deferredCloser;
this.objectMapper = objectMapper;
}
+
+ private Path getSettingsPath() throws IOException {
+ String settingsPathProperty = System.getProperty("settingsPath");
+ if (settingsPathProperty == null) {
+ return SETTINGS_DIR.resolve(SETTINGS_FILE);
+ } else {
+ return FileSystems.getDefault().getPath(settingsPathProperty);
+ }
+ }
@Override
public Settings get() {
Settings settings = null;
try {
- Files.createDirectories(SETTINGS_DIR);
- final Path settingsFile = SETTINGS_DIR.resolve(SETTINGS_FILE);
- final InputStream in = Files.newInputStream(settingsFile, StandardOpenOption.READ);
+ final Path settingsPath = getSettingsPath();
+ final InputStream in = Files.newInputStream(settingsPath, StandardOpenOption.READ);
settings = objectMapper.readValue(in, Settings.class);
settings.getDirectories().removeIf(v -> !v.isValidVaultDirectory());
} catch (IOException e) {
@@ -73,9 +81,9 @@ public class SettingsProvider implements Provider {
return;
}
try {
- Files.createDirectories(SETTINGS_DIR);
- final Path settingsFile = SETTINGS_DIR.resolve(SETTINGS_FILE);
- final OutputStream out = Files.newOutputStream(settingsFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
+ final Path settingsPath = getSettingsPath();
+ Files.createDirectories(settingsPath.getParent());
+ final OutputStream out = Files.newOutputStream(settingsPath, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
objectMapper.writeValue(out, settings);
} catch (IOException e) {
LOG.error("Failed to save settings.", e);