Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Umleitung einer DOS Anwendung in Java Applikation

Empfohlene Antworten

Veröffentlicht

Hallo,

ich habe folgende Frage:

Mit dem Befehl Runtime.getRuntime().exec(String command); kann ich ja eine Anwendung ausführen.

Ist es auch möglich, wenn diese Anwendung etwas in die DOS-Konsole schreibt, dieses abzufangen und in ein Java-Textfield zu schreiben?

Wäre super wenn mir jemand sagen könnte, ob und wie das geht.

Gruss,

Markus

  • Autor

Nun... ich versuche es nun so:

    protected void launch(String command) {

        try {

            convertStreamToString(Runtime.getRuntime().exec(command).getInputStream());

        } catch (Exception e) {

        }

    }


    protected void convertStreamToString(InputStream is) throws IOException {

        if (is != null) {

            StringBuilder sb = new StringBuilder();

            String line;

            try {

                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                while ((line = reader.readLine()) != null) {

                    sb.append(line).append("\r\n");

                    text.append(sb.toString());

                    System.out.println("running...");

                }

            } finally {

                is.close();

            }

            text.setText(sb.toString());

        } else {

            text.setText("Error\r\n");

        }

    }


    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

        Thread runner = new Thread() {


            public void run() {

                launch("tools/SamDisk.exe test.dsk a: -h0");

            }

        };

        runner.start();

    }

Wobei "text" eine "TextArea" ist...

Das Problem hier ist:

Er zeigt mir nur beim Start kurz eine Meldung an.

Das Programm aber liefert, während es läuft, Informationen an die DOS-Konsole.

(Es beschreibt/liest Disketten und gibt währenddessen die Track Informationen aus)

Jemand eine Idee, was ich ändern kann, damit ich 'während' der gesamte DOS-Prozess läuft, die Informationen erhalte?

Ich glaube der InputStream darf nicht geschlossen werden. Du willst ja schließlich auch später noch Ausgaben weiterverarbeiten, auch wenn es einen Zeitpunkt gibt, zu dem gerade keine Daten hereinkommen.

Ich sehe drei Ansätze das Problem zu lösen:

  1. Immer wieder prüfen ob der Stream etwas geliefert hat. Z. B. mit einer Endlosschleife in einem eigenen Thread.
  2. Wäre natürlich super, wenn der Stream sich melden würde, wenn Daten vorliegen. Keine Ahnung ob es da schon was etwas im JDK gibt (so was wie ein Listener).
  3. Vielleicht gibt es auch schon etwas um ein Textfield / Textarea mit einem Stream zu koppeln.

Bei den ersten zwei Varianten müsstest du selber dafür sorgen, dass hereinkommende Daten in das Textfeld geschrieben werden. Außerdem müsste der Stream vor dem Programmende geschlossen werden.

G00gl3 mal nach jtextarea + outputstream oder jtextarea + inputstream. Hab auf anhieb ein paar interessante Seiten gefunden.

  • Autor

Also ich habe nun Folgendes:

    protected Process process;


    public void Launch(boolean direction)

            throws InterruptedException, IOException {

        String file = null;

        if (direction) {

            FileDialog filedia = new FileDialog((Frame) new Frame(), "Create DSK file", FileDialog.SAVE);

            filedia.setFile("*.dsk");

            filedia.setVisible(true);

            String filename = filedia.getFile();

            if (filename != null) {

                filename = filedia.getDirectory() + filedia.getFile();

                file = filename;

            }

        } else {

            FileDialog filedia = new FileDialog((Frame) new Frame(), "Open DSK file", FileDialog.LOAD);

            filedia.setFile("*.dsk");

            filedia.setVisible(true);

            String filename = filedia.getFile();

            if (filename != null) {

                filename = filedia.getDirectory() + filedia.getFile();

                file = filename;

            }

        }


        if (file == null) {

            return;

        }


        text.setText("SAMdisk GUI 1.0 (May 10 2010), by Markus Hohmann -- http://cpc-live.com/\r\n");

        text.append("SAMdisk 3.0 (Jun  2 2009), by Simon Owen -- http://simonowen.com/samdisk/\r\n");

        String ending = "";

        if (!heads.isSelected()) {

            ending = "-h0";

        }

        String drv = "a:";

        String command = "";

        if (gaps.isSelected()) {

            ending = ending + " --gaps";

        }

        if (direction) {

            command = drv + " \"" + file + "\" " + ending;

        } else {

            command = "\"" + file + "\" " + drv + " " + ending;

        }

        process = Runtime.getRuntime().exec("tools/SamDisk.exe " + command);

        text.append("SamDisk.exe " + command + "\r\n");

        text.select(20000000, 20000000);

        InputStream is = process.getInputStream();

        InputStreamReader isr = new InputStreamReader(is);

        BufferedReader br = new BufferedReader(isr);

        String line;

        jButton1.setEnabled(false);

        jButton2.setEnabled(true);

        progress.setIndeterminate(true);

        while ((line = br.readLine()) != null) {

            if (line != null) {

                text.append(line + "\r\n");

                text.select(20000000, 20000000);

            }


        }

        br.close();

        text.append("Done...\r\n");

        text.select(20000000, 20000000);

        progress.setIndeterminate(false);

        jButton1.setEnabled(true);

        jButton2.setEnabled(false);

        prog = 0;

        process = null;

    }

Das Problem:

Fehlermeldungen und so spuckt diese Funktion aus.

Beispiel:

(Ausgabe in JTextField):

42 Tracks, Head 0

Dann werkelt er und findet dabei einen Fehler:

Failed to read sector XX

Wenns beendet ist:

Done...

Das Problem ist aber:

Während das DOS Programm arbeitet, hat es eine Anzeige, was es grad tut..

Beispiel:

Reading Track 6 Head 0

(Steigert sich dann je nach Fortschritt, bis zum Ende)

Dieses wird nicht in dem JTextField angezeigt *grummel*

Eventuell ist das ein OutputStream? Wenn ja, wie kann ich diesen Abfangen?

Also erstmal hat du ja den InputStream. Durch den InputStream kommen die Ausgaben des anderen Programms in dein Java Programm. Jetzt müssen diese Daten weiterverarbeitet bzw. Ausgegeben werden. Ansätze dafür hatte ich in meinem ersten Beitrag genannt.

In deinem Code wird der BufferedReader geschlossen, wenn keine neuen Daten vorliegen. Der Reader sollte nicht geschlossen werden, wenn gerade keine Daten vorliegen, denn das andere Programm kann ja zu einem späteren Zeitpunkt neue Daten ausgeben. Der Reader sollte erst geschlossen werden, wenn das andere Programm beendet wurde!

Ich hab just mal ne Klasse geschrieben, die einen InputStream in einen OutputStreamWriter umleitet. Hier könntest du dir anschauen, wie man dann einen OutputStream baut, der etwas in ein JTextArea ausgibt.

Ich denke damit müsstest du weiterkommen. Ansonsten noch nachfragen. Kann auch sein, dass man da noch was optimieren kann. Das sollte aber nur nötig sein, wenn dein Programm viele Ausgaben liefert. Ich halte es für wahrscheinlicher, dass man den Listener in einem eigenen Thread laufen lassen sollte. Ich würds aber erstmal so probieren. Ich habe den Code nicht getestet.

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;


public class CharInputStreamListener {


	private OutputStreamWriter outputStream;

	private BufferedReader reader;

	private boolean run;


	public CharInputStreamListener(InputStream inputStream, OutputStreamWriter outputStream) {

		this.reader = new BufferedReader(new InputStreamReader(inputStream));

		this.outputStream = outputStream;

		run = true;

		listen();

	}


	private void listen(){

		try {

		while(run){

				int data = getReader().read();

				if(data != -1){

					getOutputStream().write(data);

				}

		}

		} catch (IOException e) {

			e.printStackTrace();

		}

	}


	public BufferedReader getReader() {

		return reader;

	}


	public boolean run() {

		return run;

	}


	public void run(boolean run) {

		this.run = run;

	}


	public OutputStreamWriter getOutputStream() {

		return outputStream;

	}


}

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.