[Java(FX)] Wie kann ich ein Java-Programm ins AutoStart-Menu von Windows 10 eintragen?


31.01.2022, 20:22

Ich habe Folgendes ausprobiert, jedoch komme ich damit nicht wirklich klar.

1 Antwort

Unter der Annahme, dass die Klasse so eingesetzt auch funktioniert, brauchst du doch lediglich schauen, über welche öffentlichen Methoden sie verfügt und diese einsetzen.

Der von dir zweitverlinkte Artikel (der übrigens wohl dieselbe Klasse verwendet), zeigt sogar ein Anwendungsbeispiel, an dem man sich folglich orientieren kann.

String testPath = "SOFTWARE\\...\\Run";
WinRegistry.createKey(WinRegistry.HKEY_LOCAL_MACHINE, testPath);
WinRegistry.writeStringValue(WinRegistry.HKEY_LOCAL_MACHINE, testPath, "Test", "C:\\Users\\...");
verreisterNutzer  01.02.2022, 11:20

Ich habe es mit Copy-Paste gemacht. So viel falsch habe ich nicht machen können, aber könnte es nicht auch an jRegistryKey liegen?

Dort muss man wohl eine .jar und eine .dll einbinden. Ich habe schon nachgeschaut, wie das mit dem Einbinden der .dll-Datei funktioniert, aber im Reiter Project Structure > Modules scheint es keinen Einfluss zu haben. Laut Anleitung sollte ich die jRegistryKey.jar in Libraries einbinden. Das hat leider nichts gebracht.

Jedoch bekomme ich immer die Fehlermeldung:

Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.reflect.Method.invoke(Object, Object[])" because "com.github.xy.xy.MenuBar.Window.StartWithWindows.WinRegistry.regCreateKeyEx" is null

An WinRegistry.java wird es kaum liegen können. Oh man...

0
regex9  01.02.2022, 12:38
@verreisterNutzer

Es dürfte schon vorher (im statischen Konstruktor der Klasse) eine Exception fliegen, die allerdings nur in der Konsole ausgegeben wird. Die Zeile 57 sollte der erste Anhaltspunkt sein.

1
verreisterNutzer  01.02.2022, 13:35
@regex9

Um ehrlich zu sein... Im Internet stehen immer die gleichen Methoden und ich weiß damit einfach nicht weiter. Wenn nichts hilft, versuche ich etwas anders :/

0
regex9  01.02.2022, 16:45
@verreisterNutzer

Hast du denn geprüft, was in besagter Zeile genau passiert? Du solltest das Debugging-Tool deiner IDE dafür verwenden.

1
verreisterNutzer  01.02.2022, 17:04
@regex9

>>>>https://i.ibb.co/djSbRzH/image.png<<<<

Ich kann dort die Klasse WinRegistry.java oder StartWithWindows.java (wo ich den Registry-Eintrag mache) nicht auffinden. Ich habe die Zeilen mal aufgeklappt, aber das gehörte alles zu meinem Code aus den anderen Klassen.

Erstmal gut zu wissen, dass es beim Debuggen so aussieht - das kannte und brauchte ich vorher noch nicht. (Debug an sich kannte ich schon)

0
regex9  01.02.2022, 18:04
@verreisterNutzer

Du hast in der Zeile keinen Breakpoint gesetzt, oder?

Das Ergebnis dieses rechtsseitigen Aufrufs ist null. Warum das so ist, ist von Interesse.

regCreateKeyEx = userClass.getDeclaredMethod(
  "WindowsRegCreateKeyEx", new Class[] { int.class, byte[].class });
1
verreisterNutzer  01.02.2022, 18:32
@regex9

Ich weiß noch nicht, wie man einen Breakpoint setzt.

Ich kann nicht erkennen, was dort für ein Fehler vorliegt, außer dass regCreateKeyEx null ist, zumal ich im Internet nicht mal den selben Fehler finde. Ich habe auch mit != null überprüft, aber das bringt mir ja recht wenig.

private static int[] createKey(Preferences root, int hkey, String key)
        throws IllegalArgumentException, IllegalAccessException,
        InvocationTargetException {
    if (regCreateKeyEx != null) System.out.println("OK NULLLLL");
    return (int[]) regCreateKeyEx.invoke(root,
            new Object[]{new Integer(hkey), toCstr(key)});
}

So wie es mir ausgegeben wird, sind wohl alle Method's null. Einmal, weil auch ein Fehler wegen regOpenKey erscheint, ohne dass ich diese Methode überhaupt verwende. Als ich jedoch mal andere Methoden verwendet habe, sind auch die null gewesen. Ich habe etwas in dieser Klasse herumgestellt, aber das führte nicht zum Besseren.

0
regex9  02.02.2022, 00:55
@verreisterNutzer

Die Signaturen sind falsch. So wären sie richtig:

regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey", new Class[] { long.class, byte[].class, int.class });

regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey", new Class[] { long.class });

regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx", new Class[] { long.class, byte[].class });

regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue", new Class[] { long.class, int.class, int.class });

regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1", new Class[] { long.class });

regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx", new Class[] { long.class, int.class, int.class });

regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[] { long.class, byte[].class });

regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx", new Class[] { long.class, byte[].class, byte[].class });

regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[] { long.class, byte[].class });

regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[] { long.class, byte[].class });

Die Typen für den HKey wären also jeweils long, statt int.

An sich müsste man für die Invocations auch noch den Typ ändern. In dem Zuge könnten die Integer-Konstruktoraufrufe raus, da diese Überladung eh deprecated ist.

Allerdings schlägt auch dann noch der Zugriff auf die Methoden fehl, vermutlich da es private, native Member sind. Ich muss überlegen, ob mir dazu etwas einfällt.

Bezüglich des Debuggers:

Den ersten Artikel habe ich geteilt, weil er auf Deutsch ist. An sich sind die Grundfunktionen von Debuggern stets gleich (Breakpoints setzen, wie man im Code navigiert, usw.) und die Oberfläche daher ähnlich aufgebaut. Das heißt, wenn du Java-Code in Eclipse debuggen kannst, sollte es dir nicht schwer fallen, in irgendeiner anderen IDE das Debugging-Tool zu bedienen.

1
verreisterNutzer  02.02.2022, 18:12
@regex9

Zurzeit sieht der Code so aus (Deine Vorschläge versucht zu berücksichtigen)

Ich finde es schon fragwürdig, dass ich im Internet nur denselben Code finde, der aber nicht mal richtig funktioniert. Nicht dass es wirklich an der .dll-Datei liegt, denn die habe ich nicht eingebunden o. ä. Ich weiß nicht mehr, wie das ginge.

0
regex9  03.02.2022, 22:26
@verreisterNutzer

Der Code wird schon funktioniert haben, ist aber vermutlich nicht mit neuen OS- und JDK-Versionen kompatibel.

Welche DLL eigentlich? Ich habe auf den verlinkten Seiten dazu nichts gelesen.

Ich werde frühestens am Wochenende dazu kommen, mir das Ganze noch einmal anzuschauen.

0
verreisterNutzer  03.02.2022, 22:31
@regex9

Laut einer Beschreibung auf StackOverFlow soll man sich jRegistryKey-bin-1.4.5 herunterladen. Dieser Seitenaufruf ist aber schon unter vielen Suchergebnissen.

Ich kann sie aber bei Bedarf bei MediaFire hochladen.

🤔

Verwenden tu ich azul-15 version 15.0.5

0
regex9  06.02.2022, 03:55
@verreisterNutzer

Das ist eine separate Bibliothek, also eine Alternative, die man stattdessen nutzen könnte. Die JAR-Datei müsstest du in dein Projekt einbinden, die DLL gehört in den Projektordner. Sofern die DLL nicht erkannt wird (und ich denke, es ist generell der bessere Weg), sollte sie in den java.library.path und dann via statischem Konstruktor geladen werden.

static {
  System.loadLibrary("jRegistryKey");
}

Vermutlich wäre die Klasse, in der du die Bibliotheksfunktionen nutzen möchtest, der beste Ort dafür.

Wo besagter Pfad liegt (bzw. welche Ordner als Ablageorte für die DLL genutzt werden können), kannst du dir ausgeben lassen.

System.out.println(System.getProperty("java.library.path"));

Überschreiben ist ebenfalls möglich.

Wenn das Projekt später in eine JAR verpackt werden soll, musst du die DLL außerhalb der JAR halten oder sie vor der Ausführung (also beispielsweise während eines Installationsprozesses) entpacken.

Zurück zu der WinRegistry-Klasse:

Das java.utils.prefs-Package muss explizit für das eigene Modul freigegeben werden, damit Reflection funktioniert. Dazu kann man ein VM-Argument setzen:

--add-opens java.prefs/java.util.prefs=YourModuleName

Bezüglich notwendiger Code-Änderungen: Der HKey ist (wie schon geschrieben) immer ein long. Handles, die zurückgegeben werden, allerdings ebenso. Das kannst du hier abgleichen (von Interesse sind alle static native-Methoden, die findet man via Browsersuchfunktion ja schnell).

Du solltest dich mit dem Thema Reflection auseinandersetzen, um zu verstehen, was in der WinRegistry-Klasse passiert. Ich umschreibe es nur kurz: Zur Laufzeit werden die Methoden der WindowsPreferences-Klasse gesucht und aufgerufen.

1