Add Windows drivers installer function
This commit is contained in:
parent
f2cd0c521c
commit
4cea480bb7
21 changed files with 317 additions and 20 deletions
|
@ -30,6 +30,7 @@ import javafx.scene.layout.VBox;
|
|||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.ServiceWindow;
|
||||
import nsusbloader.ModelControllers.UpdatesChecker;
|
||||
import nsusbloader.Utilities.WindowsDrivers.DriversInstall;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -42,22 +43,16 @@ import java.util.jar.JarFile;
|
|||
|
||||
public class SettingsController implements Initializable {
|
||||
@FXML
|
||||
private CheckBox nspFilesFilterForGLCB;
|
||||
@FXML
|
||||
private CheckBox validateNSHostNameCb;
|
||||
@FXML
|
||||
private CheckBox expertModeCb;
|
||||
@FXML
|
||||
private CheckBox autoDetectIpCb;
|
||||
@FXML
|
||||
private CheckBox randPortCb;
|
||||
private CheckBox nspFilesFilterForGLCB,
|
||||
validateNSHostNameCb,
|
||||
expertModeCb,
|
||||
autoDetectIpCb,
|
||||
randPortCb;
|
||||
|
||||
@FXML
|
||||
private TextField pcIpTextField;
|
||||
@FXML
|
||||
private TextField pcPortTextField;
|
||||
@FXML
|
||||
private TextField pcExtraTextField;
|
||||
private TextField pcIpTextField,
|
||||
pcPortTextField,
|
||||
pcExtraTextField;
|
||||
|
||||
@FXML
|
||||
private CheckBox dontServeCb;
|
||||
|
@ -69,13 +64,14 @@ public class SettingsController implements Initializable {
|
|||
private CheckBox autoCheckUpdCb;
|
||||
@FXML
|
||||
private Hyperlink newVersionLink;
|
||||
@FXML
|
||||
private Button checkForUpdBtn;
|
||||
|
||||
@FXML
|
||||
private CheckBox tfXciSpprtCb;
|
||||
|
||||
@FXML
|
||||
private Button langBtn;
|
||||
private Button langBtn,
|
||||
checkForUpdBtn,
|
||||
drvInstBtn;
|
||||
@FXML
|
||||
private ChoiceBox<String> langCB;
|
||||
|
||||
|
@ -215,6 +211,15 @@ public class SettingsController implements Initializable {
|
|||
updates.setDaemon(true);
|
||||
updates.start();
|
||||
});
|
||||
|
||||
if (isWindows()){
|
||||
Region btnDrvImage = new Region();
|
||||
btnDrvImage.getStyleClass().add("regionWindows");
|
||||
drvInstBtn.setGraphic(btnDrvImage);
|
||||
drvInstBtn.setVisible(true);
|
||||
drvInstBtn.setOnAction(actionEvent -> new DriversInstall(resourceBundle));
|
||||
}
|
||||
|
||||
tfXciSpprtCb.setSelected(AppPreferences.getInstance().getTfXCI());
|
||||
|
||||
// Language settings area
|
||||
|
@ -282,6 +287,11 @@ public class SettingsController implements Initializable {
|
|||
}
|
||||
glOldVerCheck.setOnAction(e-> glOldVerChoice.setDisable(! glOldVerCheck.isSelected()) );
|
||||
}
|
||||
|
||||
private boolean isWindows(){
|
||||
return System.getProperty("os.name").toLowerCase().replace(" ", "").contains("windows");
|
||||
}
|
||||
|
||||
public boolean getNSPFileFilterForGL(){return nspFilesFilterForGLCB.isSelected(); }
|
||||
public boolean getExpertModeSelected(){ return expertModeCb.isSelected(); }
|
||||
public boolean getAutoIpSelected(){ return autoDetectIpCb.isSelected(); }
|
||||
|
|
|
@ -54,9 +54,8 @@ public class ServiceWindow {
|
|||
new Image("/res/warn_ico64x64.png"),
|
||||
new Image("/res/warn_ico128x128.png")
|
||||
);
|
||||
dialogStage.toFront();
|
||||
|
||||
alertBox.show();
|
||||
dialogStage.toFront();
|
||||
}
|
||||
/**
|
||||
* Create notification window with confirm/deny
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.WindowsDrivers;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
|
||||
public class DownloadDriversTask extends Task<String> {
|
||||
|
||||
private static final String driverFileLocationURL = "https://github.com/developersu/NS-Drivers/releases/download/v1.0/Drivers_set.exe";
|
||||
private static final long driversFileSize = 3857375;
|
||||
|
||||
private static File driversInstallerFile;
|
||||
|
||||
@Override
|
||||
protected String call() {
|
||||
if (isDriversDownloaded())
|
||||
return driversInstallerFile.getAbsolutePath();
|
||||
if (downloadDrivers())
|
||||
return driversInstallerFile.getAbsolutePath();
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isDriversDownloaded(){
|
||||
return driversInstallerFile != null && driversInstallerFile.length() == driversFileSize;
|
||||
}
|
||||
|
||||
private boolean downloadDrivers(){
|
||||
try {
|
||||
File tmpDirectory = File.createTempFile("nsul", null);
|
||||
if (! tmpDirectory.delete())
|
||||
return false;
|
||||
if (! tmpDirectory.mkdirs())
|
||||
return false;
|
||||
|
||||
tmpDirectory.deleteOnExit();
|
||||
|
||||
URL url = new URL(driverFileLocationURL);
|
||||
BufferedInputStream bis = new BufferedInputStream(url.openStream());
|
||||
|
||||
driversInstallerFile = new File(tmpDirectory, "drivers.exe");
|
||||
FileOutputStream fos = new FileOutputStream(driversInstallerFile);
|
||||
|
||||
byte[] dataBuffer = new byte[1024];
|
||||
int bytesRead;
|
||||
double totalRead = 0;
|
||||
|
||||
while ((bytesRead = bis.read(dataBuffer, 0, 1024)) != -1) {
|
||||
fos.write(dataBuffer, 0, bytesRead);
|
||||
totalRead += bytesRead;
|
||||
updateProgress(totalRead, driversFileSize);
|
||||
if (this.isCancelled()) {
|
||||
bis.close();
|
||||
fos.close();
|
||||
updateProgress(0, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bis.close();
|
||||
fos.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (IOException | SecurityException e){
|
||||
updateMessage("Error: "+e.toString().replaceAll(":.*$", ""));
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.WindowsDrivers;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import nsusbloader.AppPreferences;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class DriversInstall {
|
||||
|
||||
private static volatile boolean isRunning;
|
||||
|
||||
private Label runInstallerStatusLabel;
|
||||
|
||||
public DriversInstall(ResourceBundle rb){
|
||||
|
||||
if (DriversInstall.isRunning)
|
||||
return;
|
||||
|
||||
DriversInstall.isRunning = true;
|
||||
|
||||
DownloadDriversTask downloadTask = new DownloadDriversTask();
|
||||
|
||||
Button cancelButton = new Button(rb.getString("btn_Cancel"));
|
||||
|
||||
HBox hBoxInformation = new HBox();
|
||||
hBoxInformation.setAlignment(Pos.TOP_LEFT);
|
||||
hBoxInformation.getChildren().add(new Label(rb.getString("windowBodyDownloadDrivers")));
|
||||
|
||||
ProgressBar progressBar = new ProgressBar();
|
||||
progressBar.setPrefWidth(Double.MAX_VALUE);
|
||||
progressBar.progressProperty().bind(downloadTask.progressProperty());
|
||||
|
||||
Label downloadStatusLabel = new Label();
|
||||
downloadStatusLabel.setWrapText(true);
|
||||
downloadStatusLabel.textProperty().bind(downloadTask.messageProperty());
|
||||
|
||||
runInstallerStatusLabel = new Label();
|
||||
runInstallerStatusLabel.setWrapText(true);
|
||||
|
||||
Pane fillerPane1 = new Pane();
|
||||
Pane fillerPane2 = new Pane();
|
||||
|
||||
VBox parentVBox = new VBox();
|
||||
parentVBox.setAlignment(Pos.TOP_CENTER);
|
||||
parentVBox.setFillWidth(true);
|
||||
parentVBox.setSpacing(5.0);
|
||||
parentVBox.setPadding(new Insets(5.0));
|
||||
parentVBox.setFillWidth(true);
|
||||
parentVBox.getChildren().addAll(
|
||||
hBoxInformation,
|
||||
fillerPane1,
|
||||
downloadStatusLabel,
|
||||
runInstallerStatusLabel,
|
||||
fillerPane2,
|
||||
progressBar,
|
||||
cancelButton
|
||||
); // TODO:FIX
|
||||
|
||||
VBox.setVgrow(fillerPane1, Priority.ALWAYS);
|
||||
VBox.setVgrow(fillerPane2, Priority.ALWAYS);
|
||||
|
||||
Stage stage = new Stage();
|
||||
|
||||
stage.setTitle(rb.getString("windowTitleDownloadDrivers"));
|
||||
stage.getIcons().addAll(
|
||||
new Image("/res/dwnload_ico32x32.png"), //TODO: REDRAW
|
||||
new Image("/res/dwnload_ico48x48.png"),
|
||||
new Image("/res/dwnload_ico64x64.png"),
|
||||
new Image("/res/dwnload_ico128x128.png")
|
||||
);
|
||||
stage.setMinWidth(400);
|
||||
stage.setMinHeight(150);
|
||||
|
||||
Scene mainScene = new Scene(parentVBox, 405, 155);
|
||||
|
||||
mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
|
||||
stage.setOnHidden(windowEvent -> {
|
||||
downloadTask.cancel(true );
|
||||
DriversInstall.isRunning = false;
|
||||
});
|
||||
|
||||
stage.setScene(mainScene);
|
||||
stage.show();
|
||||
stage.toFront();
|
||||
|
||||
downloadTask.setOnSucceeded(event -> {
|
||||
cancelButton.setText(rb.getString("btn_Close"));
|
||||
|
||||
String returnedValue = downloadTask.getValue();
|
||||
|
||||
if (returnedValue == null)
|
||||
return;
|
||||
|
||||
if (runInstaller(returnedValue))
|
||||
stage.close();
|
||||
});
|
||||
|
||||
Thread downloadThread = new Thread(downloadTask);
|
||||
downloadThread.start();
|
||||
|
||||
cancelButton.setOnAction(actionEvent -> {
|
||||
downloadTask.cancel(true );
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
|
||||
private boolean runInstaller(String pathToFile) {
|
||||
try {
|
||||
Runtime.getRuntime().exec("cmd /c "+pathToFile);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e){
|
||||
runInstallerStatusLabel.setText("Error: "+e.toString());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,11 @@
|
|||
<Label text="%tab2_Lbl_Language" />
|
||||
<ChoiceBox fx:id="langCB" prefWidth="100.0" />
|
||||
<Button fx:id="langBtn" mnemonicParsing="false" text="OK" />
|
||||
<VBox alignment="CENTER_RIGHT" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Button fx:id="drvInstBtn" mnemonicParsing="false" text="%tab2_Btn_InstallDrivers" visible="false" />
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets left="5.0" />
|
||||
|
|
|
@ -63,3 +63,8 @@ failure_txt=Failed
|
|||
btn_Select=Select
|
||||
btn_InjectPayloader=Inject payload
|
||||
tabNXDT_Btn_Start=Start!
|
||||
tab2_Btn_InstallDrivers=Download and install drivers
|
||||
windowTitleDownloadDrivers=Download and install drivers
|
||||
windowBodyDownloadDrivers=Downloading drivers (libusbK v3.0.7.0)...
|
||||
btn_Cancel=Cancel
|
||||
btn_Close=Close
|
|
@ -43,3 +43,5 @@ tab2_Lbl_AllowXciNszXczDesc=Von einigen Drittanbietern verwendet, welche XCI/NSZ
|
|||
tab2_Lbl_Language=Sprache
|
||||
windowBodyRestartToApplyLang=Bitte die Applikation neustarten um die Einstellungen zu \u00FCbernehmen.
|
||||
tab2_Cb_GLshowNspOnly=Nur *.nsp in GoldLeaf zeigen.
|
||||
btn_Cancel=Abbrechen
|
||||
|
||||
|
|
|
@ -41,4 +41,6 @@ windowBodyNewVersionUnknown=Une erreur s'est produite\nPeut-\u00EAtre des probl\
|
|||
tab2_Cb_AllowXciNszXcz=Autoriser la s\u00E9lection de fichiers XCI / NSZ / XCZ pour TinFoil
|
||||
tab2_Lbl_AllowXciNszXczDesc=Utilis\u00E9 par certaines applications tierces prenant en charge XCI/NSZ/XCZ et utilisant le protocole de transfert TinFoil. Ne changez pas en cas de doute.
|
||||
tab2_Lbl_Language=La langue
|
||||
btn_Cancel=Annuler
|
||||
|
||||
|
||||
|
|
|
@ -62,3 +62,5 @@ done_txt=Fatto!
|
|||
failure_txt=Fallito
|
||||
btn_Select=Seleziona
|
||||
btn_InjectPayloader=Inietta payload
|
||||
btn_Cancel=Annulla
|
||||
|
||||
|
|
|
@ -62,3 +62,5 @@ done_txt=Feito!
|
|||
failure_txt=Falhou
|
||||
btn_Select=Selecionar
|
||||
btn_InjectPayloader=Injetar payload
|
||||
btn_Cancel=Cancelar
|
||||
|
||||
|
|
|
@ -63,4 +63,9 @@ failure_txt=\u041D\u0435\u0443\u0434\u0430\u0447\u0430
|
|||
btn_Select=\u0412\u044B\u0431\u0440\u0430\u0442\u044C
|
||||
btn_InjectPayloader=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C payload
|
||||
tabNXDT_Btn_Start=\u0421\u0442\u0430\u0440\u0442!
|
||||
tab2_Btn_InstallDrivers=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430
|
||||
windowTitleDownloadDrivers=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430
|
||||
windowBodyDownloadDrivers=\u0421\u043A\u0430\u0447\u0438\u0432\u0430\u0435\u043C \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u044B (libusbK v3.0.7.0)...
|
||||
btn_Cancel=\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C
|
||||
btn_Close=\u0417\u0430\u043A\u0440\u044B\u0442\u044C
|
||||
|
||||
|
|
|
@ -43,3 +43,5 @@ tab2_Lbl_AllowXciNszXczDesc=Usado por algunas aplicaciones de terceros que sopor
|
|||
tab2_Lbl_Language=Idioma
|
||||
windowBodyRestartToApplyLang=Por favor, reinicie el programa para aplicar los cambios.
|
||||
tab2_Cb_GLshowNspOnly=Mostrar solo *.nsp en GoldLeaf.
|
||||
btn_Cancel=Cancelar
|
||||
|
||||
|
|
|
@ -62,4 +62,9 @@ done_txt=\u0413\u043E\u0442\u043E\u0432\u043E!
|
|||
failure_txt=\u041D\u0435\u0432\u0434\u0430\u0447\u0430
|
||||
btn_Select=\u0412\u0438\u0431\u0440\u0430\u0442\u0438
|
||||
btn_InjectPayloader=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 payload
|
||||
tabNXDT_Btn_Start=\u0421\u0442\u0430\u0440\u0442!
|
||||
tabNXDT_Btn_Start=\u0421\u0442\u0430\u0440\u0442!
|
||||
tab2_Btn_InstallDrivers=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0430 \u0432\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0438
|
||||
windowTitleDownloadDrivers=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0430 \u0432\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0438
|
||||
windowBodyDownloadDrivers=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0443\u0454\u043C\u043E \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0438 (libusbK v3.0.7.0)...
|
||||
btn_Cancel=\u0412\u0456\u0434\u043C\u0456\u043D\u0438\u0442\u0438
|
||||
btn_Close=\u0417\u0430\u043A\u0440\u0438\u0442\u0438
|
||||
|
|
|
@ -61,3 +61,5 @@ windowTitleErrorPort=C\u1ED5ng thi\u1EBFt l\u1EADp kh\u00F4ng ch\u00EDnh x\u00E1
|
|||
windowTitleNewVersionAval=C\u00F3 phi\u00EAn b\u1EA3n m\u1EDBi
|
||||
windowTitleNewVersionNOTAval=Ch\u01B0a c\u00F3 phi\u00EAn b\u1EA3n m\u1EDBi
|
||||
windowTitleNewVersionUnknown=Kh\u00F4ng th\u1EC3 ki\u1EC3m tra phi\u00EAn b\u1EA3n m\u1EDBi
|
||||
btn_Cancel=H\u1EE7y B\u1ECF
|
||||
|
||||
|
|
|
@ -43,3 +43,5 @@ tab2_Lbl_AllowXciNszXczDesc=\u7528\u4E8E\u4E00\u4E9B\u652F\u6301XCI/NSZ/XCZ\u548
|
|||
tab2_Lbl_Language=\u8BED\u8A00
|
||||
windowBodyRestartToApplyLang=\u8BF7\u91CD\u542F\u5E94\u7528\u4EE5\u5E94\u7528\u66F4\u6539\u3002
|
||||
tab2_Cb_GLshowNspOnly=\u5728GoldLeaf\u4EC5\u5C55\u793A*.NSP\u6587\u4EF6
|
||||
btn_Cancel=\u53D6\u6D88
|
||||
|
||||
|
|
|
@ -403,6 +403,14 @@
|
|||
.nxdt.label .text {
|
||||
-fx-fill: #cb0010;
|
||||
}
|
||||
|
||||
.regionWindows {
|
||||
-fx-shape: "M3,12V6.75L9,5.43V11.91L3,12M20,3V11.75L10,11.9V5.21L20,3M3,13L9,13.09V19.9L3,18.75V13M20,13.25V22L10,20.09V13.1L20,13.25Z";
|
||||
-fx-background-color: #f7fafa;
|
||||
-size: 17.5;
|
||||
-fx-min-height: -size;
|
||||
-fx-min-width: 17.5;
|
||||
}
|
||||
//
|
||||
//.lineGradient {
|
||||
// -fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #00c8fc 30%, transparent 45%);
|
||||
|
|
|
@ -320,4 +320,11 @@
|
|||
}
|
||||
.nxdt.label .text {
|
||||
-fx-fill: #9d010e;
|
||||
}
|
||||
.regionWindows {
|
||||
-fx-shape: "M3,12V6.75L9,5.43V11.91L3,12M20,3V11.75L10,11.9V5.21L20,3M3,13L9,13.09V19.9L3,18.75V13M20,13.25V22L10,20.09V13.1L20,13.25Z";
|
||||
-fx-background-color: #2c2c2c;
|
||||
-size: 17.5;
|
||||
-fx-min-height: -size;
|
||||
-fx-min-width: 17.5;
|
||||
}
|
BIN
src/main/resources/res/dwnload_ico128x128.png
Normal file
BIN
src/main/resources/res/dwnload_ico128x128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
BIN
src/main/resources/res/dwnload_ico32x32.png
Normal file
BIN
src/main/resources/res/dwnload_ico32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
src/main/resources/res/dwnload_ico48x48.png
Normal file
BIN
src/main/resources/res/dwnload_ico48x48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
BIN
src/main/resources/res/dwnload_ico64x64.png
Normal file
BIN
src/main/resources/res/dwnload_ico64x64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
Loading…
Reference in a new issue