diff --git a/.gitignore b/.gitignore index b4dc8d0..a65e01e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ TO-DO.md dist target/ +app.log .mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ diff --git a/HowToRun.md b/HowToRun.md new file mode 100644 index 0000000..856f92a --- /dev/null +++ b/HowToRun.md @@ -0,0 +1,40 @@ +## 🖥️ Installation (2 clicks — for recruiters) + +The application is distributed as a **standalone EXE** built with `jpackage`. + +### ✔ Requirements +Nothing except: +- Windows 10/11 (Currently on win 10 System Logs are not working - TODO) +- Local user profile +- Windows PowerShell (built-in on Windows 10/11) + +> **Java is bundled inside the EXE**. +> You do NOT need to install Java. + +### ✔ Running the app +1. Download `SystemLogAnalyzer.rar` +2. unpack it with winrar anywhere. +3. Double-click on SystemLogAnalyzer.exe +4. (Optional) If Security logs are selected → confirm Windows UAC popup + +That's all. + +## 📦 How it works + +### 1. Choose: +- directory for storing exported CSVs +- directory for saving reports +- log types (Application / System / Security) + +### 2. The app: +- runs PowerShell → exports CSV +- parses records +- loads them into a JavaFX table + +### 3. You can: +- filter +- search +- inspect details +- refresh logs anytime + +All without touching Event Viewer manually. \ No newline at end of file diff --git a/HowToRun_PL.md b/HowToRun_PL.md new file mode 100644 index 0000000..45c5d5b --- /dev/null +++ b/HowToRun_PL.md @@ -0,0 +1,40 @@ +## 🖥️ Instalacja (2 kliknięcia — dla rekruterów) + +Aplikacja jest dystrybuowana jako **samodzielny plik EXE** zbudowany przy użyciu `jpackage`. + +### ✔ Wymagania +Nic poza: +- Windows 10/11 +- Lokalnym profilem użytkownika +- Windows PowerShell (built-in on Windows 10/11) + +> **Java jest dołączona do pliku EXE**. +> NIE musisz instalować Javy. + +### ✔ Uruchamianie aplikacji +1. Pobierz `SystemLogAnalyzer.exe` +2. Wypakuj program w dowolne miejsce +3. Kliknij go dwukrotnie na SystemLogAnalyzer.exe +4. (Opcjonalnie) Jeśli wybrano dzienniki zabezpieczeń → potwierdź wyskakujące okienko UAC systemu Windows + +To wszystko. + +## 📦 Jak to działa + +### 1. Wybierz: +- katalog do przechowywania wyeksportowanych plików CSV +- katalog do zapisywania raportów +- typy logów (Aplikacja/System/Zabezpieczenia) + +### 2. Aplikacja: +- uruchamia program PowerShell → eksportuje plik CSV +- analizuje rekordy +- ładuje je do tabeli JavaFX + +### 3. Możesz: +- filtrować +- wyszukiwać +- sprawdzać szczegóły +- odświeżać logi w dowolnym momencie + +Wszystko to bez ręcznego uruchamiania Podglądu zdarzeń. \ No newline at end of file diff --git a/README.md b/README.md index 72888d8..ac1a073 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# System Log Analyzer (Work in progress — v0.1 MVP) +# System Log Analyzer (Work in progress — v0.2) **System Log Analyzer** A standalone Windows desktop application for IT professionals to export, parse and analyze Windows Event Logs with a fast, clean and modern UI. diff --git a/pom.xml b/pom.xml index 04fd624..842a6f4 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ - + org.springframework spring-context @@ -46,12 +46,19 @@ 25-ea+1 + + + net.java.dev.jna + jna + 5.13.0 + + - + org.apache.maven.plugins maven-compiler-plugin @@ -71,7 +78,7 @@ - + org.apache.maven.plugins maven-surefire-plugin diff --git a/src/main/java/com/project/system_log_analyzer/SystemLogAnalyzerApp.java b/src/main/java/com/project/system_log_analyzer/SystemLogAnalyzerApp.java index 47c9a4a..f5869ec 100644 --- a/src/main/java/com/project/system_log_analyzer/SystemLogAnalyzerApp.java +++ b/src/main/java/com/project/system_log_analyzer/SystemLogAnalyzerApp.java @@ -8,13 +8,35 @@ import javafx.stage.Stage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; + public class SystemLogAnalyzerApp extends Application { + private boolean app_Log = false; + private AnnotationConfigApplicationContext springContext; + private static Boolean elevatedFlag = false; // Admin permissions + @Override public void init() { springContext = new AnnotationConfigApplicationContext(SpringConfig.class); + + if (app_Log) { // debug app.log in main directory + PrintStream out = null; + try { + out = new PrintStream(new FileOutputStream("app.log", true), true); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + System.setOut(out); + System.setErr(out); + } + + + } @Override @@ -22,8 +44,25 @@ public void start(Stage primaryStage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/WelcomeView.fxml")); loader.setControllerFactory(springContext::getBean); - Parent root = loader.load(); + boolean elevated = getParameters().getRaw().contains("--elevated"); + elevatedFlag = elevated; // Admin profile checker + System.out.println("ARGS = " + getParameters().getRaw()); // Admin permission check to debug file + + com.project.system_log_analyzer.config.appConfig cfg = springContext.getBean(com.project.system_log_analyzer.config.appConfig.class); + + if (elevated) { + cfg.setCsvSecurity(true); + } + + try { + cfg.setCsvSecurity(elevated); + IO.println("Elevated mode: " + elevated); + } catch (Exception e) { + System.err.println("Could not set elevated flag in appConfig: " + e.getMessage()); + } + + Parent root = loader.load(); SpringConfig.APP_READY = true; Scene scene = new Scene(root); @@ -37,6 +76,10 @@ public void stop() { springContext.close(); } + public static boolean isElevated() { + return Boolean.TRUE.equals(elevatedFlag); + } + public static void main(String[] args) { launch(args); } diff --git a/src/main/java/com/project/system_log_analyzer/config/SpringConfig.java b/src/main/java/com/project/system_log_analyzer/config/SpringConfig.java index 8aecbdc..a9185d5 100644 --- a/src/main/java/com/project/system_log_analyzer/config/SpringConfig.java +++ b/src/main/java/com/project/system_log_analyzer/config/SpringConfig.java @@ -1,6 +1,8 @@ package com.project.system_log_analyzer.config; +import com.project.system_log_analyzer.SystemLogAnalyzerApp; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/project/system_log_analyzer/config/appConfig.java b/src/main/java/com/project/system_log_analyzer/config/appConfig.java index 4629dab..09bd5f4 100644 --- a/src/main/java/com/project/system_log_analyzer/config/appConfig.java +++ b/src/main/java/com/project/system_log_analyzer/config/appConfig.java @@ -9,6 +9,33 @@ public class appConfig { private boolean csvApplication; private boolean csvSystem; private boolean csvSecurity; + private boolean noLogs; + private boolean saveInExeDir; + private boolean relaunch; + + public boolean isRelaunch() { + return relaunch; + } + + public void setRelaunch(boolean relaunch) { + this.relaunch = relaunch; + } + + public boolean isNoLogs() { + return noLogs; + } + + public void setNoLogs(boolean noLogs) { + this.noLogs = noLogs; + } + + public boolean isSaveInExeDir() { + return saveInExeDir; + } + + public void setSaveInExeDir(boolean saveInExeDir) { + this.saveInExeDir = saveInExeDir; + } public boolean isCsvSecurity() { return csvSecurity; diff --git a/src/main/java/com/project/system_log_analyzer/controller/MainWindowFXController.java b/src/main/java/com/project/system_log_analyzer/controller/MainWindowFXController.java index 3d38742..1f2807b 100644 --- a/src/main/java/com/project/system_log_analyzer/controller/MainWindowFXController.java +++ b/src/main/java/com/project/system_log_analyzer/controller/MainWindowFXController.java @@ -175,6 +175,9 @@ public void onRefreshClick() { refreshButton.setDisable(true); logTable.setDisable(true); loadingLabel.setText("Refreshing logs… Please wait. (Time of loading depends on number of logs)"); + logTable.getSelectionModel().clearSelection(); + logTable.getFocusModel().focus(-1); // Details unexpected pop-up || Fixed + onClearFilters(); // Clear all filters Task> task = new Task>() { @Override @@ -222,6 +225,8 @@ protected List call() throws Exception { } @FXML public void onSearchChanged() { + logTable.getSelectionModel().clearSelection(); + logTable.getFocusModel().focus(-1); // Details unexpected pop-up || Fixed applyFilters(); } @@ -244,6 +249,9 @@ public void onFilterChanged() { private void applyFilters() { if (logs == null) return; + logTable.getSelectionModel().clearSelection(); + logTable.getFocusModel().focus(-1); + String input = searchField.getText().toLowerCase().trim(); // input correctness check diff --git a/src/main/java/com/project/system_log_analyzer/controller/WelcomeViewFXController.java b/src/main/java/com/project/system_log_analyzer/controller/WelcomeViewFXController.java index 61982cb..fbb1112 100644 --- a/src/main/java/com/project/system_log_analyzer/controller/WelcomeViewFXController.java +++ b/src/main/java/com/project/system_log_analyzer/controller/WelcomeViewFXController.java @@ -1,7 +1,10 @@ package com.project.system_log_analyzer.controller; +import com.project.system_log_analyzer.SystemLogAnalyzerApp; import com.project.system_log_analyzer.config.ApplicationContextProvider; import com.project.system_log_analyzer.config.appConfig; +import com.project.system_log_analyzer.system.WindowsElevationManager; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; @@ -28,12 +31,23 @@ public class WelcomeViewFXController { @FXML private CheckBox systemButton; @FXML private CheckBox securityButton; @FXML private Label securityLabel; + @FXML private Button logFilesDirButton; + @FXML private Button reportDirButton; + + @FXML private CheckBox noLogsBox; + @FXML private CheckBox saveInAppDirectoryBox; + @Autowired public appConfig appConfig; @FXML public void initialize() { System.out.println("Controller initialized, appConfig = " + appConfig); + + if (appConfig.isCsvSecurity()) { + securityButton.setSelected(true); + securityLabel.setText("Admin permission granted!"); + } } @@ -42,9 +56,11 @@ private void scan(ActionEvent event) throws IOException { String logDir = logFilesDirField.getText(); String reportDir = reportDirField.getText(); - if (logDir.isEmpty() || reportDir.isEmpty()) { - informationLabel.setText("Please select both directories."); - return; + if (!noLogsBox.isSelected()) { + if (logDir.isEmpty() || reportDir.isEmpty()) { + informationLabel.setText("Please select both directories."); + return; + } } if (!appButton.isSelected() && !systemButton.isSelected() && !securityButton.isSelected()) { @@ -57,7 +73,7 @@ private void scan(ActionEvent event) throws IOException { ApplicationContext springContext = ApplicationContextProvider.getApplicationContext(); FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/LoadingScreen.fxml")); - loader.setControllerFactory(springContext::getBean); // Spring Boot starter by JavaFX !!IMPORTANT!! + loader.setControllerFactory(springContext::getBean); // Spring starter by JavaFX !!IMPORTANT!! Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); @@ -103,19 +119,36 @@ private void systemButtonON(ActionEvent event) throws IOException { @FXML private void securityButtonON(ActionEvent event) throws IOException { + + if (SystemLogAnalyzerApp.isElevated()) { // Admin ckeck for Security Logs + securityLabel.setText("Admin permission granted!"); + appConfig.setCsvSecurity(securityButton.isSelected()); + return; + } + if (securityButton.isSelected()) { boolean proceed = askForSecurityPermission(); if (!proceed) { securityButton.setSelected(false); - securityLabel.setText("Admin permission required!"); appConfig.setCsvSecurity(false); + securityLabel.setText("Admin permission required!"); return; + } + + boolean relaunchStarted = WindowsElevationManager.relaunchAsAdmin("--elevated"); + + if (relaunchStarted) { + appConfig.setRelaunch(true); + Platform.exit(); } else { - securityLabel.setText("Admin permission granted!"); - appConfig.setCsvSecurity(true); + appConfig.setCsvSecurity(false); + securityButton.setSelected(false); + securityLabel.setText("(Requires Admin Permission)"); } + } else { appConfig.setCsvSecurity(false); + securityButton.setSelected(false); securityLabel.setText("(Requires Admin Permission)"); } } @@ -129,4 +162,76 @@ private boolean askForSecurityPermission() { return alert.showAndWait().filter(btn -> btn == ButtonType.OK).isPresent(); } + @FXML + private void noLogsBoxOn(ActionEvent event) throws IOException { + if (noLogsBox.isSelected()) { + appConfig.setNoLogs(true); + + appConfig.setSaveInExeDir(false); + saveInAppDirectoryBox.setSelected(false); + saveInAppDirectoryBox.setDisable(true); + + logFilesDirButton.setDisable(true); + reportDirButton.setDisable(true); + + logFilesDirField.clear(); + reportDirField.clear(); + + appConfig.setLogsDir(null); + appConfig.setReportDir(null); + + } else { + appConfig.setNoLogs(false); + saveInAppDirectoryBox.setDisable(false); + + if (appConfig.isSaveInExeDir()) { + String baseDir = System.getProperty("user.dir"); + String logs = baseDir + "/logs"; + String reports = baseDir + "/reports"; + + appConfig.setSaveInExeDir(true); + appConfig.setLogsDir(logs); + appConfig.setReportDir(reports); + + logFilesDirField.setText(logs); + reportDirField.setText(reports); + + logFilesDirButton.setDisable(true); + reportDirButton.setDisable(true); + + } else { + logFilesDirButton.setDisable(false); + reportDirButton.setDisable(false); + } + } + } + @FXML + private void saveInAppDirectoryBoxOn(ActionEvent event) throws IOException { + if (saveInAppDirectoryBox.isSelected()) { + appConfig.setSaveInExeDir(true); + + String baseDir = System.getProperty("user.dir"); + String logs = baseDir + "/logs"; + String reports = baseDir + "/reports"; + + logFilesDirField.setText(logs); + reportDirField.setText(reports); + + logFilesDirButton.setDisable(true); + reportDirButton.setDisable(true); + + //new File(logs).mkdirs(); + //new File(reports).mkdirs(); + + appConfig.setLogsDir(logs); + appConfig.setReportDir(reports); + + } else { + appConfig.setSaveInExeDir(false); + + logFilesDirButton.setDisable(false); + reportDirButton.setDisable(false); + + } + } } diff --git a/src/main/java/com/project/system_log_analyzer/core/FileLoggerService.java b/src/main/java/com/project/system_log_analyzer/core/FileLoggerService.java index 778712a..bb5c76d 100644 --- a/src/main/java/com/project/system_log_analyzer/core/FileLoggerService.java +++ b/src/main/java/com/project/system_log_analyzer/core/FileLoggerService.java @@ -57,13 +57,23 @@ private void ensureLogFile() { if (logsDir == null) { String path = config.getLogsDir(); - if (path == null) { - System.out.println("FileLoggerService: logsDir not set yet — skipping log."); - return; // + + if (path == null || path.isBlank()) { + + String baseDir = System.getProperty("user.dir"); + path = baseDir + "/temp_"; + + new File(path).mkdirs(); + + config.setLogsDir(path); + config.setReportDir(path); + + System.out.println("FileLoggerService: Using TEMP directory for logs: " + path); } logsDir = new File(path); if (!logsDir.exists()) logsDir.mkdirs(); + logFile = new File(logsDir, "log_" + nOfLogPart + ".log"); createLogFileIfMissing(); } diff --git a/src/main/java/com/project/system_log_analyzer/io/WindowsEventExporter.java b/src/main/java/com/project/system_log_analyzer/io/WindowsEventExporter.java index eda0b19..5938ef6 100644 --- a/src/main/java/com/project/system_log_analyzer/io/WindowsEventExporter.java +++ b/src/main/java/com/project/system_log_analyzer/io/WindowsEventExporter.java @@ -21,7 +21,7 @@ public class WindowsEventExporter { public enum LogType { APPLICATION("Application"), SYSTEM("System"), - SECURITY("Security"); // TODO - Test in real environment (.exe/.jar) + SECURITY("Security"); private final String logName; LogType(String logName) { @@ -42,14 +42,18 @@ public WindowsEventExporter(appConfig config) { public Path exportToCsv(LogType type) { // Method responsible for exporting logs from windows try { - String baseDir = config.getLogsDir() != null && !config.getLogsDir().isEmpty() - ? config.getLogsDir() : "logs/exported"; + String baseDir; + if (config.getLogsDir() == null || config.getLogsDir().isBlank()) { + baseDir = System.getProperty("user.dir") + "/temp_"; + } else { + baseDir = config.getLogsDir(); + } - File dir = new File(baseDir, "exported"); - if (!dir.exists()) dir.mkdirs(); + File exportedDir = new File(baseDir, "exported"); + if (!exportedDir.exists()) exportedDir.mkdirs(); String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")); - Path outputFile = Path.of(dir.getAbsolutePath(), type.getLogName() + "_" + timestamp + ".csv"); + Path outputFile = Path.of(exportedDir.getAbsolutePath(), type.getLogName() + "_" + timestamp + ".csv"); // Powershell command String command = String.format( @@ -78,26 +82,45 @@ public Path exportToCsv(LogType type) { // Method responsible for exporting logs } } - public Path exportSecurityLogsAsAdmin() { // Method responsible for exporting Security logs with admin permissions + public Path exportSecurityLogsAsAdmin() { try { - String baseDir = config.getLogsDir() != null && !config.getLogsDir().isEmpty() - ? config.getLogsDir() : "logs/exported"; + String baseDir; + if (config.getLogsDir() == null || config.getLogsDir().isBlank()) { + baseDir = System.getProperty("user.dir") + "/temp_"; + } else { + baseDir = config.getLogsDir(); + } - File dir = new File(baseDir, "exported"); - if (!dir.exists()) dir.mkdirs(); + File exportedDir = new File(baseDir, "exported"); + if (!exportedDir.exists()) exportedDir.mkdirs(); String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")); - Path outputFile = Path.of(dir.getAbsolutePath(), "Security_" + timestamp + ".csv"); + Path outputFile = Path.of(exportedDir.getAbsolutePath(), "Security_" + timestamp + ".csv"); - String powershellCommand = - "Start-Process powershell -Verb RunAs -ArgumentList " + - "\"Get-WinEvent -LogName Security | " + + String ps = + "Get-WinEvent -LogName Security -MaxEvents 15000 | " + "Select-Object TimeCreated, Id, LevelDisplayName, ProviderName, Message | " + - "Export-Csv -Path '" + outputFile.toAbsolutePath() + "' -NoTypeInformation -Encoding UTF8\""; + "Export-Csv -Path '" + outputFile.toAbsolutePath() + + "' -NoTypeInformation -Encoding UTF8"; + - ProcessBuilder pb = new ProcessBuilder("Powershell.exe", "-Command", powershellCommand); + + List cmd = new ArrayList<>(); + cmd.add("powershell.exe"); + cmd.add("-NoProfile"); + cmd.add("-ExecutionPolicy"); + cmd.add("Bypass"); + cmd.add("-Command"); + cmd.add(ps); + + ProcessBuilder pb = new ProcessBuilder(cmd); + pb.redirectErrorStream(true); Process process = pb.start(); + try (BufferedReader out = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + out.lines().forEach(System.out::println); + } + int exit = process.waitFor(); if (exit == 0) { @@ -114,6 +137,7 @@ public Path exportSecurityLogsAsAdmin() { // Method responsible for exporting S return null; } + public List exportSelected() { List paths = new ArrayList<>(); diff --git a/src/main/java/com/project/system_log_analyzer/system/AppShutdownHandler.java b/src/main/java/com/project/system_log_analyzer/system/AppShutdownHandler.java index 8a5cba4..198a3ab 100644 --- a/src/main/java/com/project/system_log_analyzer/system/AppShutdownHandler.java +++ b/src/main/java/com/project/system_log_analyzer/system/AppShutdownHandler.java @@ -1,6 +1,7 @@ package com.project.system_log_analyzer.system; import com.project.system_log_analyzer.config.SpringConfig; +import com.project.system_log_analyzer.config.appConfig; import com.project.system_log_analyzer.core.FileLoggerService; import com.project.system_log_analyzer.core.FileReportExporter; import org.springframework.beans.factory.annotation.Autowired; @@ -8,16 +9,25 @@ import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Comparator; + @Component public class AppShutdownHandler { private FileLoggerService fileLoggerService; private FileReportExporter reportExporter; + private appConfig appConfig; + private Boolean elevatedFlag; @Autowired - public AppShutdownHandler(FileLoggerService fileLoggerService, FileReportExporter reportExporter) { + public AppShutdownHandler(FileLoggerService fileLoggerService, FileReportExporter reportExporter, appConfig config) { this.fileLoggerService = fileLoggerService; this.reportExporter = reportExporter; + this.appConfig = config; } @EventListener(ContextClosedEvent.class) @@ -27,14 +37,47 @@ public void onShutdown() { return; } - try { - System.out.println("AppShutdownHandler - Application is shutting down! Flushing logs and exporting report..."); - fileLoggerService.flushLogToMainFile(); - System.out.println("AppShutdownHandler - Shutdown tasks completed successfully."); - } catch (Exception e) { - System.err.println("AppShutdownHandler - Error during shutdown tasks: " + e.getMessage()); - e.printStackTrace(); + if (appConfig.isNoLogs()) { + Path dir = Paths.get(appConfig.getLogsDir()); + + try { + if (Files.exists(dir)) { + deleteDirectoryRecursively(dir); + System.out.println("NoLogs = true → temporary directory removed."); + } + } catch (Exception e) { + System.err.println("Failed to delete temp directory: " + e.getMessage()); + } + return; + } + + if (appConfig.isRelaunch() || appConfig.getLogsDir() == null || appConfig.getLogsDir().isBlank()) { + System.out.println("Skipping flush — elevated admin relaunch or before Spring Injection"); + return; + } else { + try { + System.out.println("AppShutdownHandler - Application is shutting down! Flushing logs and exporting report..."); + fileLoggerService.flushLogToMainFile(); + System.out.println("AppShutdownHandler - Shutdown tasks completed successfully."); + } catch (Exception e) { + System.err.println("AppShutdownHandler - Error during shutdown tasks: " + e.getMessage()); + e.printStackTrace(); + } } + + + } + // Method for correct deletion of temp files when noLogs is selected + private void deleteDirectoryRecursively(Path path) throws IOException { + if (!Files.exists(path)) return; + + Files.walk(path) + .sorted(Comparator.reverseOrder()) + .forEach(p -> { + try { + Files.deleteIfExists(p); + } catch (IOException ignored) {} + }); } } diff --git a/src/main/java/com/project/system_log_analyzer/system/WindowsElevationManager.java b/src/main/java/com/project/system_log_analyzer/system/WindowsElevationManager.java new file mode 100644 index 0000000..fee16ff --- /dev/null +++ b/src/main/java/com/project/system_log_analyzer/system/WindowsElevationManager.java @@ -0,0 +1,56 @@ +package com.project.system_log_analyzer.system; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.WString; +import com.sun.jna.win32.W32APIOptions; + +import java.io.File; + +public class WindowsElevationManager { + + public interface Shell32 extends com.sun.jna.Library { + Shell32 INSTANCE = Native.load("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS); + + Pointer ShellExecuteW( + Pointer hwnd, + WString lpOperation, + WString lpFile, + WString lpParameters, + WString lpDirectory, + int nShowCmd + ); + } + + public static boolean relaunchAsAdmin(String params) { + try { + String exePath = new File(System.getProperty("user.dir"), + "System_Log_Analyzer.exe").getAbsolutePath(); + + Pointer p = Shell32.INSTANCE.ShellExecuteW( + null, + new WString("runas"), + new WString(exePath), + params == null ? null : new WString(params), + null, + 1 + ); + + long result = Pointer.nativeValue(p); + return result > 32; + + } catch (Throwable t) { + t.printStackTrace(); + return false; + } + } + + public static boolean isCurrentUserAdmin() { + try { + new java.io.File("C:\\Windows\\System32\\config\\systemprofile").list(); + return true; + } catch (Throwable e) { + return false; + } + } +} diff --git a/src/main/resources/view/WelcomeView.fxml b/src/main/resources/view/WelcomeView.fxml index 04c532f..966ade8 100644 --- a/src/main/resources/view/WelcomeView.fxml +++ b/src/main/resources/view/WelcomeView.fxml @@ -38,6 +38,15 @@ + + +