# Batch Datei Problem, Programm nur einmal starten



## javanoob19 (25. Jan 2010)

hey leute, 



also nach langer relativ erfolgreicher programmierphase bin ich nun auf ein erneutes Manko meines Mp3 Players gestoßen.


ich habe eine Batch datei, die wenn man auf eine Mp3 datei doppelklickt mein java programm starten und den Titel abspielt. Leider tut sie das jedesmal auch wenn der Player bereits geöffnet ist.

kan man das verhindern ? und wenn der player bereits offen ist soll die neue mp3 datei abgespielt werden sprich der neue pfad übergeben werden.


Mit der bitte um Hilfe 

Stephan 

DANKE an all diejenigen die hier immer so zahlreich helfen


----------



## Ebenius (25. Jan 2010)

Es gibt verschiedene Möglichkeiten, sowas zu lösen. So zum Beispiel könnte es funktionieren:

```
/* $Id$ */

/* Copyright 2010 Sebastian Haufe

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       [url]http://www.apache.org/licenses/LICENSE-2.0[/url]

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

package com.ebenius;

import java.io.*;
import java.net.*;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class SingleInstanceAppTest {

  public static void main(String[] args)
        throws IOException, InterruptedException, BackingStoreException {
    if (args.length == 0) {
      System.out.println("Nothing to do.");
      System.exit(0);
    }

    final Preferences node =
          Preferences.userNodeForPackage(SingleInstanceAppTest.class);
    int port = node.getInt("SingleInstanceApp.listenPort", -1);
    boolean running = false;
    if (port != -1) {
      try {
        // App läuft schon
        final Socket socket = new Socket(InetAddress.getLocalHost(), port);
        final OutputStreamWriter w =
              new OutputStreamWriter(socket.getOutputStream());
        w.write(args[0]);
        w.flush();
        w.close();
        socket.close();
        running = true;
      } catch (ConnectException ex) {
        System.out.printf("Cannot connect to port %d.%n", port);
      }
    }

    if (!running) {
      port = createTCPListener();
      node.putInt("SingleInstanceApp.listenPort", port);
      node.flush();
      handleCommand(args[0]);

      // just for my test app: wait for infinity
      final Object obj = new Object();
      synchronized (obj) {
        obj.wait();
      }
    }
  }

  private static int createTCPListener() throws IOException {
    final ServerSocket serverSock = new ServerSocket();
    serverSock.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
    final Thread listenerThread = new Thread(new Runnable() {

      public void run() {
        try {
          while (true) {
            final Socket socket = serverSock.accept();
            final InputStream is = socket.getInputStream();
            final InputStreamReader r = new InputStreamReader(is);
            final StringBuilder sb = new StringBuilder();
            int c;
            while ((c = r.read()) != -1) {
              sb.append((char) c);
            }
            handleCommand(sb.toString());
            socket.close();
          }
        } catch (IOException ex) {} finally {
          applicationExit();
        }
      }
    });
    listenerThread.setName("SingleInstanceApp.tcpListener");
    listenerThread.setDaemon(true);
    listenerThread.setPriority(Thread.MIN_PRIORITY);
    listenerThread.start();
    System.out.println("Now listening to port: " + serverSock.getLocalPort());
    return serverSock.getLocalPort();
  }

  static void handleCommand(String cmd) {
    System.out.println("Now Playing: " + cmd);
  }

  static void applicationExit() {
    // remove config when application ends
    final Preferences node =
          Preferences.userNodeForPackage(SingleInstanceAppTest.class);
    node.remove("SingleInstanceApp.listenPort");
  }
}
```
Ebenius


----------



## javanoob19 (25. Jan 2010)

wow... hmm danke .. aber was macht dein code genau ? 


und vorallem wie wird er angewendet und kommuniziert mit meinem java programm 

sorry bin nuoch ein neuling kann man das nicht mit der .bat datei machen ?? 


Die schaut jetzt grad folgendermaßen aus:


```
tasklist | findstr /i java.exe
echo %errorlevel%

if ERRORLEVEL 1 (cd /D %~d0%~p0 
javaw musik %1) else ()
```



funktioniert aber nicht so wie ich es will, weil es dass prgramm trotzdem öffnet obwol java.exe bereits ausgeführt wird ... 


naja und von pfad der mp3 datei übergeben kann hier auch keine reden sein ....



mit der Bitte um Hilfe 
!!!



Stehan


----------



## L-ectron-X (25. Jan 2010)

Java Blog Buch : D) Java-Anwendung nur einmal ausführen


----------



## javanoob19 (25. Jan 2010)

Einfacher geht das nicht ?? 

wow  ziemlicher aufwand ... hast du vl ein beispiel wie das konkret implementiert wurde ?? 


lg.. 


danke für eure mühe


----------



## aedu00 (25. Jan 2010)

Habe deinen Code nicht gelesen... vielleich ist die Antwort total daneben, aber wenn man von einer Klasse nur eine Instanz will, dann gibt es dafür eine ganz "einfach" Lösung: Singleton (Entwurfsmuster) ? Wikipedia

Hier der wichtige Codeteil von der Wikipedia-Seite:


```
public final class Singleton {
 
      /**
       * Privates Klassenattribut,
       * wird beim erstmaligen Gebrauch (nicht beim Laden) der Klasse erzeugt
       */
      private static Singleton instance;
 
      /** Konstruktor ist privat, Klasse darf nicht von außen instanziiert werden. */
      private Singleton() {}
 
      /**
       * Statische Methode „getInstance()“ liefert die einzige Instanz der Klasse zurück.
       * Ist synchronisiert und somit thread-sicher.
       */
      public synchronized static Singleton getInstance() {
          if (instance == null) {
              instance = new Singleton();
          }
          return instance;
      }
  }
```


----------



## Ebenius (25. Jan 2010)

aedu00, Deine Antwort hat tatsächlich nix mit dem Problem zu tun. Der Themeneröffner möchte sicherstellen, dass nur ein Prozess läuft. Wenn man das zweite mal das Programm ausführt, soll das erste gestartetete Programm die Argumente bekommen und das zweite Programm sich gleich wieder beenden.

javanoob, ich hab mir den Link von LeX nicht durchgelesen. Aber ich nehme an, dass es in die Richtung meines Beispiels oben geht. Das Programm guckt in irgendeiner Konfiguration nach (ich hab java.util.Preferences dafür verwendet), ob eine Instanz schon läuft. Ist das nicht der Fall, öffnet es einen ServerSocket und hört und schreibt den Port in die Konfiguration. Das nächste mal, dass das Programm gestartet wird, findet es nun den Port in der Konfiguration. Also versucht es, sich mit dem ServerSocket der ersten Instanz zu verbinden. Wenn das funktioniert, überträgt es einfach das Argument 0 über die Verbindung zum ersten Programm. Danach beendet es sich. Das erste Programm erhält die übertragenen Daten und macht damit was es möchte.

Ebenius


----------



## javanoob19 (25. Jan 2010)

hast du so etwas schon mal verwirklicht ?? 



oder irgendjemand anders ?? 



ich habe mir nun dies tutorial angesehen ...


aber werde daraus nur bedingt schlau ...


----------



## Ebenius (25. Jan 2010)

Na mein Beispiel oben tut doch genau das. 

Kopier's Dir und starte's zweimal.

Ebenius


----------



## L-ectron-X (25. Jan 2010)

Ich habe mal ein einfaches Beispiel mit RMI hier vorgestellt. Muss mal suchen, ob ich dieses Beispiel wiederfinde.

Edit: Hier: http://www.java-forum.org/allgemeine-java-themen/34662-verhindern-programm-mehrmals-geoeffnet-2.html


----------

