# Autostart eine Jar per Java Code



## Andyx1975 (5. November 2010)

Hallo,

ich habe eine Programm geschrieben. Jetzt möchte ich, dass das Programm beim Rechnerstart automatisch gestartet wird. Das Starten soll im Programm selbst an und ausschaltbar sein. Hat jemand eine Idee wie das Programmieren kann? Wenn möglich wäre ein plattformunabhängiges starten des Programmes gut.

Danke
Andy


----------



## Bratkartoffel (5. November 2010)

Hallo,

als Ansatz mal folgender Vorschlag:
Windows:
Einen Eintrag in die Registry:
- HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run: Für globalen Autostart
- HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run: Für den Benutzer

Bei Linux stellen sich mehrere Fragen:
- Benötigt das Programm eine grafische Oberfläche?
- Welche Distributionen willst du abdecken?
- Soll der Benutzer damit interagieren? (oder läuft das Ding als Daemon)

Bei Ersteren und Zweiteren müsstest du schauen, welchen Desktop der Benutzer verwendet (z.B.: KDE, Gnome, XFCE) und dann dir die Konfigurationsdatei suchen. Dies kannst du somit nur für den aktuellen Benutzer machen, für einen "globalen" Autostart bräuchtest du vermutlich root-Rechte.

Bei letzten könntest du ein Script in /etc/init.d erstellen und dann mit update-rc.d das aktivieren. (man update-rc.d)


Wie du das bei Apple und Solaris machen kannst, kann ich dir nicht sagen.

Gruß
BK


----------



## Andyx1975 (5. November 2010)

naja über die Linux geschichte mach ich mir erstmal noch keine Gedanken...das mit den Windows Reg keys sieht gut aus  Wie muss ich die Setzen damit es funktioniert? Also welche Werte eintragen?


----------



## Andyx1975 (5. November 2010)

übrigens danke noch für die schnelle antwort!!


----------



## ComFreek (5. November 2010)

Du musst eine Zeichenfolge in dem Registry-Schlüssel erstellen, sprich z.B.

```
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\yourjava
```
Und als Wert den Pfad zu deinem Programm.
Du kannst auch Umgebungsvariablen nutzen:

```
%ProgramFiles%\myjavaapp\myapp.jar
```
Wenn du Parameter übergeben willst oder Ordner Leerzeichen enthalten, musst du doppelte Anführungsstriche drum machen:

```
%ProgramFiles%\myjavaapp\myapp.jar "-autostart"
```

PS: Wie man sowas in Java realisiert kann ich dir nicht sagen. Ich bin kein Java-Programmierer


----------



## Andyx1975 (8. November 2010)

ah cool...ich probiere es heute Abend aus und poste die Lösung dann...Danke Comfreek...hat mir viel geholfen...die Info reicht schon aus.

Gruß
Andy


----------



## Andyx1975 (11. November 2010)

Also meine Lösung sieht jetzt wie folgt aus...die folgende Klasse manipuliert die Regkeys:



```
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;

public class WinRegistry {
  // inspired by
  // http://javabyexample.wisdomplug.com/java-concepts/34-core-java/62-java-registry-wrapper.html
  // http://www.snipcode.org/java/1-java/23-java-class-for-accessing-reading-and-writing-from-windows-registry.html
  // http://snipplr.com/view/6620/accessing-windows-registry-in-java/
  public static final int HKEY_CURRENT_USER = 0x80000001;
  public static final int HKEY_LOCAL_MACHINE = 0x80000002;
  public static final int REG_SUCCESS = 0;
  public static final int REG_NOTFOUND = 2;
  public static final int REG_ACCESSDENIED = 5;

  private static final int KEY_ALL_ACCESS = 0xf003f;
  private static final int KEY_READ = 0x20019;
  private static Preferences userRoot = Preferences.userRoot();
  private static Preferences systemRoot = Preferences.systemRoot();
  private static Class<? extends Preferences> userClass = userRoot.getClass();
  private static Method regOpenKey = null;
  private static Method regCloseKey = null;
  private static Method regQueryValueEx = null;
  private static Method regEnumValue = null;
  private static Method regQueryInfoKey = null;
  private static Method regEnumKeyEx = null;
  private static Method regCreateKeyEx = null;
  private static Method regSetValueEx = null;
  private static Method regDeleteKey = null;
  private static Method regDeleteValue = null;

  static {
    try {
      regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
          new Class[] { int.class, byte[].class, int.class });
      regOpenKey.setAccessible(true);
      regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",
          new Class[] { int.class });
      regCloseKey.setAccessible(true);
      regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",
          new Class[] { int.class, byte[].class });
      regQueryValueEx.setAccessible(true);
      regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
          new Class[] { int.class, int.class, int.class });
      regEnumValue.setAccessible(true);
      regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",
          new Class[] { int.class });
      regQueryInfoKey.setAccessible(true);
      regEnumKeyEx = userClass.getDeclaredMethod(  
          "WindowsRegEnumKeyEx", new Class[] { int.class, int.class,  
              int.class });  
      regEnumKeyEx.setAccessible(true);
      regCreateKeyEx = userClass.getDeclaredMethod(  
          "WindowsRegCreateKeyEx", new Class[] { int.class,  
              byte[].class });  
      regCreateKeyEx.setAccessible(true);  
      regSetValueEx = userClass.getDeclaredMethod(  
          "WindowsRegSetValueEx", new Class[] { int.class,  
              byte[].class, byte[].class });  
      regSetValueEx.setAccessible(true); 
      regDeleteValue = userClass.getDeclaredMethod(  
          "WindowsRegDeleteValue", new Class[] { int.class,  
              byte[].class });  
      regDeleteValue.setAccessible(true); 
      regDeleteKey = userClass.getDeclaredMethod(  
          "WindowsRegDeleteKey", new Class[] { int.class,  
              byte[].class });  
      regDeleteKey.setAccessible(true); 
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  private WinRegistry() {  }

  /**
   * Read a value from key and value name
   * @param hkey   HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @param valueName
   * @return the value
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static String readString(int hkey, String key, String valueName) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      return readString(systemRoot, hkey, key, valueName);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      return readString(userRoot, hkey, key, valueName);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Read value(s) and value name(s) form given key 
   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @return the value name(s) plus the value(s)
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static Map<String, String> readStringValues(int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      return readStringValues(systemRoot, hkey, key);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      return readStringValues(userRoot, hkey, key);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Read the value name(s) from a given key
   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @return the value name(s)
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static List<String> readStringSubKeys(int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      return readStringSubKeys(systemRoot, hkey, key);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      return readStringSubKeys(userRoot, hkey, key);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Create a key
   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void createKey(int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int [] ret;
    if (hkey == HKEY_LOCAL_MACHINE) {
      ret = createKey(systemRoot, hkey, key);
      regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
    }
    else if (hkey == HKEY_CURRENT_USER) {
      ret = createKey(userRoot, hkey, key);
      regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
    if (ret[1] != REG_SUCCESS) {
      throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key);
    }
  }

  /**
   * Write a value in a given key/value name
   * @param hkey
   * @param key
   * @param valueName
   * @param value
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void writeStringValue
    (int hkey, String key, String valueName, String value) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      writeStringValue(systemRoot, hkey, key, valueName, value);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      writeStringValue(userRoot, hkey, key, valueName, value);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Delete a given key
   * @param hkey
   * @param key
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void deleteKey(int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int rc = -1;
    if (hkey == HKEY_LOCAL_MACHINE) {
      rc = deleteKey(systemRoot, hkey, key);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      rc = deleteKey(userRoot, hkey, key);
    }
    if (rc != REG_SUCCESS) {
      throw new IllegalArgumentException("rc=" + rc + "  key=" + key);
    }
  }

  /**
   * delete a value from a given key/value name
   * @param hkey
   * @param key
   * @param value
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void deleteValue(int hkey, String key, String value) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int rc = -1;
    if (hkey == HKEY_LOCAL_MACHINE) {
      rc = deleteValue(systemRoot, hkey, key, value);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      rc = deleteValue(userRoot, hkey, key, value);
    }
    if (rc != REG_SUCCESS) {
      throw new IllegalArgumentException("rc=" + rc + "  key=" + key + "  value=" + value);
    }
  }

  // =====================

  private static int deleteValue
    (Preferences root, int hkey, String key, String value)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
    if (handles[1] != REG_SUCCESS) {
      return handles[1];  // can be REG_NOTFOUND, REG_ACCESSDENIED
    }
    int rc =((Integer) regDeleteValue.invoke(root,  
        new Object[] { 
          new Integer(handles[0]), toCstr(value) 
          })).intValue();
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return rc;
  }

  private static int deleteKey(Preferences root, int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int rc =((Integer) regDeleteKey.invoke(root,  
        new Object[] { new Integer(hkey), toCstr(key) })).intValue();
    return rc;  // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
  }

  private static String readString(Preferences root, int hkey, String key, String value)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
    if (handles[1] != REG_SUCCESS) {
      return null; 
    }
    byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
        new Integer(handles[0]), toCstr(value) });
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return (valb != null ? new String(valb).trim() : null);
  }

  private static Map<String,String> readStringValues
    (Preferences root, int hkey, String key)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    HashMap<String, String> results = new HashMap<String,String>();
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
    if (handles[1] != REG_SUCCESS) {
      return null;
    }
    int[] info = (int[]) regQueryInfoKey.invoke(root,
        new Object[] { new Integer(handles[0]) });

    int count = info[2]; // count  
    int maxlen = info[3]; // value length max
    for(int index=0; index<count; index++)  {
      byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
          new Integer
            (handles[0]), new Integer(index), new Integer(maxlen + 1)});
      String value = readString(hkey, key, new String(name));
      results.put(new String(name).trim(), value);
    }
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return results;
  }

  private static List<String> readStringSubKeys
    (Preferences root, int hkey, String key)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    List<String> results = new ArrayList<String>();
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_READ) 
        });
    if (handles[1] != REG_SUCCESS) {
      return null;
    }
    int[] info = (int[]) regQueryInfoKey.invoke(root,
        new Object[] { new Integer(handles[0]) });

    int count = info[2]; // count  
    int maxlen = info[3]; // value length max
    for(int index=0; index<count; index++)  {
      byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
          new Integer
            (handles[0]), new Integer(index), new Integer(maxlen + 1)
          });
      results.add(new String(name).trim());
    }
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return results;
  }

  private static int [] createKey(Preferences root, int hkey, String key)
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    return  (int[]) regCreateKeyEx.invoke(root,
        new Object[] { new Integer(hkey), toCstr(key) });
  }

  private static void writeStringValue 
    (Preferences root, int hkey, String key, String valueName, String value) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });

    regSetValueEx.invoke(root,  
        new Object[] { 
          new Integer(handles[0]), toCstr(valueName), toCstr(value) 
          }); 
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
  }

  // utility
  private static byte[] toCstr(String str) {
    byte[] result = new byte[str.length() + 1];

    for (int i = 0; i < str.length(); i++) {
      result[i] = (byte) str.charAt(i);
    }
    result[str.length()] = 0;
    return result;
  }
}
```


*Das Anlegen wird durch die folgende Methode surchgeführt. Hier muss "<meinProgram>" durch den Programmnamen ausgetauscht werden.*


```
public void createRegValue() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException  
  {

	  // ermittelt das Installtionsverzeichnis
	  File file = new File(System.getProperty("user.dir"));
	  String appPath = (String.valueOf(file).replace(":\\\\", ":\\") + "\\<meinProgram>");
	 
	 //schreibt den Reg Key in die Registry 
      WinRegistry.writeStringValue(
          WinRegistry.HKEY_LOCAL_MACHINE, 
          "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 
          "JClipper", 
          appPath);

      System.out.println("Done." );
      
  } // End of Method
```

Alternativ könnt man auch JNI verwenden.


----------



## Andyx1975 (11. November 2010)

so jetzt habe ich noch ein Problem...die Jar wird jedoch gestartet...funktioniert jedoch nicht. Wenn ich die Jar per Doppelklick starte ist es kein Problem...startet fehlerfrei. Nur per Autostart bekomme ich keine GUI angezeigt. Kann mir jemand sagen warum?

Mein Eintrag in der "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\" sieht wie folgt aus:

Key "<ProgrammName>"
Value: "java -jar C:\Programme\<Programmordner\<dateiname>.jar"

Habe auch schon folgendes Probiert:
Value: "C:\Programme\<Programmordner\<dateiname>.jar"

wieso startet das Programm nicht richtig. Wo liegt mein Fehler? Jemand eine Idee?


----------



## Andyx1975 (11. November 2010)

also ich habe unter C\Programme\<ProgammOrdnerName>

einen Ordner Names "/conf" einen conf file sowie sprachdateien liegen.

diese lade ich zB. mit den folgenden Zeilen:

File f = new File("conf/configuration.properties");
Properties prop = new Properties();
prop.loadFromXML(new FileInputStream(f));

Wenn ich über dos starte bekomme ich eine Fehlermeldung, dass die conf Datei nicht gefunden wurde? Deswegen kann die Gui auch ned gestartet werden, weil da parameter hierzu gepflegt werden. Was kann ich tun?


----------



## ComFreek (11. November 2010)

Andyx1975 hat gesagt.:


> Wenn ich über dos starte bekomme ich eine Fehlermeldung, dass die conf Datei nicht gefunden wurde? Deswegen kann die Gui auch ned gestartet werden, weil da parameter hierzu gepflegt werden. Was kann ich tun?


Benutzt dein Programm relative Pfade? Es könnte sein, dass der Umgebungsordner nicht automatisch auf deinen Programmordner gesetzt ist.
Wenn das so ist, fällt mir momentan kein Weg ein, dieses in der Registry zu lösen.


----------



## EnderKill98 (29. Dezember 2013)

Du kannst einfach den Befehl wie man den in der Cmd.exe ausführen würde ausführen lassen.
glaub der Befehl startet mit "hkey".
Code:
Runtime.getRuntime().exec("Befehl hier rein");
Um den Pfad rauszukriegenkann man eine File anlegen. So:
String FileName = System.getProperty("java.classpath"); //Der Wert heisst villeicht etwas anders da dies nur am handy geschrieben wurde
File myjar = new File(FileName);
String Path = myjar.getAbsolutePath();
//Beispiel wie der Path lauten könnte: "C:/Users/HansVader/Desktop/JavaTool.jar"

Den Path dann im Runtime-Befehl nutzen.

Ich hoffe ich hab dir geholfen.

LG,
Ein erfahrener (Bukkit/)Java-Programmierer.


----------

