[Java(FX)] Wie kann ich ein Java-Programm ins AutoStart-Menu von Windows 10 eintragen?
Damit meine ich nicht zwingend das bloße Kopieren in den "C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"-Ordner, sondern das hinzufügen eines Registry-Eintrags oder sonstiges. Dabei muss aber beachtet werden, dass beim Autostart immer der aktuelle Pfad genommen wird, wo auch das Programm drin liegt., denn sonst wird das Programm nicht mehr gestartet - logisch.
Ich habe bereits 2 Registry-Dateien geschrieben:
Add:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run]
"Test"="C:\\Users\\USER\\Desktop\\Programm.jar"
Remove:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run]
"Test"=-
Jedoch sieht es wohl so aus, als müsste man so etwas in Java ganz anders umsetzen.
Angenommen, es gibt ein CheckMenuItem. Wenn die ausgewählt ist, startet sich das Programm beim Hochfahren mit Windows und wenn die nicht ausgewählt ist, dann halt eben nicht. Ich habe schon Webseiten wie diese hier angeschaut, jedoch kann ich so erst mal nicht viel damit anfangen.
Danke.
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\\...");
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.
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 :/
Hast du denn geprüft, was in besagter Zeile genau passiert? Du solltest das Debugging-Tool deiner IDE dafür verwenden.
>>>>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)
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 });
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.
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:
- https://javabeginners.de/IDE/Eclipse_Screenshot-Tutorials/Debugging_mit_Eclipse.php
- https://www.jetbrains.com/help/idea/debugging-code.html
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.
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.
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.
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
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.
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:
An WinRegistry.java wird es kaum liegen können. Oh man...