Skip to content

Commit

Permalink
fix: Fixed Illegal Character Exception in update in Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
SaptarshiSarkar12 committed Feb 18, 2024
1 parent 14c5f70 commit 1fc1d3d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 45 deletions.
40 changes: 24 additions & 16 deletions CLI/src/main/java/cli/updater/ExecuteUpdate.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,52 @@

public class ExecuteUpdate {
private static final MessageBroker M = Environment.getMessageBroker();
private final File currentExecutable;
private final File latestExecutable;
private final File currentExecutableFile;
private final File latestExecutableFile;

public ExecuteUpdate(File currentExecutable, File latestExecutable) {
this.currentExecutable = currentExecutable;
this.latestExecutable = latestExecutable;
public ExecuteUpdate(File currentExecutableFile, File latestExecutableFile) {
this.currentExecutableFile = currentExecutableFile;
this.latestExecutableFile = latestExecutableFile;
}

public boolean setExecutablePermission() {
boolean isExecutablePermissionGranted = latestExecutable.setExecutable(true);
boolean isExecutablePermissionGranted = latestExecutableFile.setExecutable(true);
if (!isExecutablePermissionGranted) {
M.msgUpdateError("Failed to set executable permission for the latest executable!");
return false;
}
boolean isWritablePermissionGranted = latestExecutable.setWritable(true);
boolean isWritablePermissionGranted = latestExecutableFile.setWritable(true);
if (!isWritablePermissionGranted) {
M.msgUpdateError("Failed to set write permission for the latest executable!");
return false;
}
boolean isReadablePermissionGranted = latestExecutable.setReadable(true);
boolean isReadablePermissionGranted = latestExecutableFile.setReadable(true);
if (!isReadablePermissionGranted) {
M.msgUpdateError("Failed to set read permission for the latest executable!");
return false;
}
return true;
}

public boolean executeUpdate() throws IOException {
String currentExecutablePath = currentExecutable.toPath().toString();
boolean isCurrentExecutableRenamed = currentExecutable.renameTo(new File(currentExecutable.getName() + ".old"));
public boolean executeUpdate() {
String currentExecutablePath = currentExecutableFile.toPath().toString();
boolean isCurrentExecutableRenamed = currentExecutableFile.renameTo(Paths.get(currentExecutableFile.getParent()).resolve(currentExecutableFile.getName() + ".old").toFile());
if (!isCurrentExecutableRenamed) {
M.msgUpdateError("Failed to replace current executable with the latest one!");
M.msgUpdateError("Failed to rename the current executable!");
return false;
}
try {
Files.move(latestExecutableFile.toPath(), Paths.get(currentExecutablePath), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
M.msgUpdateError("Failed to replace the current executable with the latest version!");
return false;
}
try {
Files.deleteIfExists(Paths.get(currentExecutablePath + ".old"));
} catch (IOException e) {
M.msgUpdateError("Failed to delete the old version of Drifty!");
return false;
}
Files.move(latestExecutable.toPath(), Paths.get(currentExecutablePath), StandardCopyOption.REPLACE_EXISTING);
Files.deleteIfExists(Paths.get(currentExecutablePath + ".old"));
M.msgUpdateInfo("Update successful!");
M.msgUpdateInfo("Please restart Drifty to see the changes!");
return true;
}
}
43 changes: 27 additions & 16 deletions CLI/src/main/java/main/Drifty_CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
import utils.Logger;

import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -214,6 +212,10 @@ private static void checkAndUpdateDrifty(boolean askForInstallingUpdate) {
messageBroker.msgUpdateInfo("Downloading update...");
if (!downloadUpdate()) {
messageBroker.msgUpdateError("Failed to update Drifty!");
} else {
messageBroker.msgUpdateInfo("Update successful!");
messageBroker.msgUpdateInfo("Please restart Drifty to see the changes!");
System.exit(0);
}
}
}
Expand All @@ -227,24 +229,33 @@ private static boolean isDriftyUpdateChecked() {

private static boolean downloadUpdate() {
try {
final URL updateURL = Constants.updateURL;
Path currentExecutablePath = Paths.get(URLDecoder.decode(Drifty_CLI.class.getProtectionDomain().getCodeSource().getLocation().getPath(), StandardCharsets.UTF_8)).toAbsolutePath();
Path tmpFolder = Files.createTempDirectory("Drifty").toAbsolutePath();
tmpFolder.toFile().deleteOnExit();
FileDownloader downloader = new FileDownloader(updateURL.toString(), currentExecutablePath.getFileName().toString(), tmpFolder.toString());
// "Current executable" means the executable currently running i.e., the one that is outdated.
File currentExecutableFile = new File(Drifty_CLI.class.getProtectionDomain().getCodeSource().getLocation().toURI());
// "Latest executable" means the executable that is to be downloaded and installed i.e., the latest version.
// "tmpFolder" is the temporary folder where the latest executable will be downloaded to.
File tmpFolder = Files.createTempDirectory("Drifty").toFile();
tmpFolder.deleteOnExit();
File latestExecutableFile = Paths.get(tmpFolder.getPath()).resolve(currentExecutableFile.getName()).toFile();
FileDownloader downloader = new FileDownloader(Constants.updateURL.toString(), currentExecutableFile.getName(), tmpFolder.toString());
downloader.run();
File latestExecutable = new File(tmpFolder.toString(), currentExecutablePath.getFileName().toString());
File currentExecutable = currentExecutablePath.toFile();
ExecuteUpdate updateExecutor = new ExecuteUpdate(currentExecutable, latestExecutable);
if (!updateExecutor.setExecutablePermission()) {
return false;
if (latestExecutableFile.exists() && latestExecutableFile.isFile() && latestExecutableFile.length() > 0) {
// If the latest executable was successfully downloaded, set the executable permission and execute the update.
ExecuteUpdate updateExecutor = new ExecuteUpdate(currentExecutableFile, latestExecutableFile);
messageBroker.msgLogInfo("Setting executable permission for the latest version of Drifty...");
if (updateExecutor.setExecutablePermission()) {
messageBroker.msgLogInfo("Executing update...");
return updateExecutor.executeUpdate();
}
} else {
return updateExecutor.executeUpdate();
messageBroker.msgUpdateError("Failed to download update!");
return false;
}
} catch (IOException e) {
messageBroker.msgUpdateError("Failed to download update! " + e.getMessage());
messageBroker.msgUpdateError("Failed to create temporary folder for downloading update! " + e.getMessage());
} catch (URISyntaxException e) {
messageBroker.msgUpdateError("Failed to get the location of the current executable! " + e.getMessage());
} catch (Exception e) {
messageBroker.msgUpdateError("Failed to download update! An unknown error occurred! " + e.getMessage());
messageBroker.msgUpdateError("Failed to update Drifty! " + e.getMessage());
}
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions GUI/src/main/java/gui/updater/ExecuteUpdate.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ public void executeUpdate() {
} else {
String currentExecutablePathString = currentExecutableFile.toPath().toString();
ProcessBuilder runCurrentExecutable = new ProcessBuilder(currentExecutableFile.getAbsolutePath());
boolean isCurrentExecutableRenamed = currentExecutableFile.renameTo(new File(Paths.get(currentExecutableFile.getParent()).resolve(currentExecutableFile.getName() + ".old").toString()));
boolean isCurrentExecutableRenamed = currentExecutableFile.renameTo(Paths.get(currentExecutableFile.getParent()).resolve(currentExecutableFile.getName() + ".old").toFile());
if (!isCurrentExecutableRenamed) {
M.msgUpdateError("Failed to replace the current version of Drifty!");
new ConfirmationDialog("Update Failed", "Failed to replace the current version of Drifty!", true, true).getResponse();
M.msgUpdateError("Failed to rename the current version of Drifty!");
new ConfirmationDialog("Update Failed", "Failed to rename the current version of Drifty!", true, true).getResponse();
return;
}
try {
Expand Down
21 changes: 11 additions & 10 deletions GUI/src/main/java/ui/UIController.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
Expand Down Expand Up @@ -99,17 +97,17 @@ private void downloadUpdate() {
String previouslySelectedDir = getDir(); // Save the download folder selected before the update was initiated.
try {
// "Current executable" means the executable currently running i.e., the one that is outdated.
URI currentExecutableURI = Paths.get(URLDecoder.decode(Drifty_GUI.class.getProtectionDomain().getCodeSource().getLocation().getPath(), StandardCharsets.UTF_8)).toUri();
File currentExecutableFile = new File(currentExecutableURI);
File currentExecutableFile = new File(Drifty_GUI.class.getProtectionDomain().getCodeSource().getLocation().toURI());
// "Latest executable" means the executable that is to be downloaded and installed i.e., the latest version.
// "tmpFolder" is the temporary folder where the latest executable will be downloaded to.
URI tmpFolderURI = Files.createTempDirectory("Drifty").toUri();
File tmpFolder = Files.createTempDirectory("Drifty").toFile();
tmpFolder.deleteOnExit();
// For Mac, the latest executable is a ".pkg" file as it is the only working way to update the application, i.e., by installing a new version.
// For other OS, the latest executable name along with the extension is the same as that of the current executable.
String latestExecutableName = OS.isMac() ? "Drifty_GUI.pkg" : currentExecutableFile.getName();
URI latestExecutableURI = Paths.get(tmpFolderURI).resolve(latestExecutableName).toUri();
File latestExecutableFile = new File(latestExecutableURI);
latestExecutableFile.getParentFile().deleteOnExit();
File latestExecutableFile = Paths.get(tmpFolder.getPath()).resolve(latestExecutableName).toFile();
// Download the latest executable
Job updateJob = new Job(Constants.updateURL.toString(), latestExecutableFile.getParent(), latestExecutableName, false);
Job updateJob = new Job(Constants.updateURL.toString(), latestExecutableFile.getParent(), latestExecutableFile.getName(), false);
addJob(updateJob);
Thread downloadUpdate = new Thread(batchDownloader());
downloadUpdate.start();
Expand All @@ -132,6 +130,9 @@ private void downloadUpdate() {
} catch (IOException e) {
M.msgUpdateError("Failed to create temporary folder for downloading update! " + e.getMessage());
new ConfirmationDialog("Update Failed", "Failed to create temporary folder for downloading update! " + e.getMessage(), true, true).getResponse();
} catch (URISyntaxException e) {
M.msgUpdateError("Failed to get the location of the current executable! " + e.getMessage());
new ConfirmationDialog("Update Failed", "Failed to get the location of the current executable! " + e.getMessage(), true, true).getResponse();
} catch (Exception e) {
M.msgUpdateError("Failed to update! An unknown error occurred! " + e.getMessage());
new ConfirmationDialog("Update Failed", "Failed to update! An unknown error occurred! " + e.getMessage(), true, true).getResponse();
Expand Down

0 comments on commit 1fc1d3d

Please sign in to comment.