[Java] cmd.exe onderbreken, Hoe?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
Ben bezig met een programma en het aansturen van cmd.exe werkt nu uitstekend door middel van de InputStreamReader en bijbehorende klassen/methoden zoals de getErrorStream() en getInputStream(). In ieder geval dat werkt perfect. Doet wat het moet doen namelijk cmd.exe aansturen. Ik stuur er dan gewoon commands naartoe zoals je ook doet in de normale cmd.exe. Bv dir. Nu ik een commando stuur wat een extern process gaat runnen zoals x264.exe om video te encoderen. Zodra ik mijn java applicatie sluit loopt het process door omdat het gestart is. In de normale cmd.exe kan ik dan Ctrl+C doen om het huidig process binnen cmd.exe te killen/te stoppen. Maar vanuit java kan ik geen Ctrl+C sturen naar cmd.exe??? In ieder geval ik krijg het niet voor elkaar cq zou niet weten hoe het probleem te tackelen. Via google heb ik volgend stuk code gevonden maar weet niet precies wat het doet en weet niet echt hoe ik dat moet implementeren:

Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
cleanUp();
}
};

Dit lijkt me niet echt het gewenste resultaat te geven. De bedoeling is dus dat als ik de applicatie sluit de draaiende processen binnen cmd te killen. Cmd zelf word al gesloten uiteraard. Maar omdat het extern process door blijft draaien is dat dus niet zo handig. Tevens maak ik er een knopje bij om het draaiende process te killen. Wie kan me verder helpen?

Ruisende versterker: schakel je subwoofer in.


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 09:20

Haan

dotnetter

je kan toch ook exit typen om cmd af te sluiten?

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
Haan schreef op vrijdag 26 december 2008 @ 19:24:
je kan toch ook exit typen om cmd af te sluiten?
Exit word pas uitgevoerd als het process klaar is. Niet zo handig als het process een uur of 4 duurt. Ctrl+C stopt het process direct. Exit pas als het process klaar is.

[ Voor 8% gewijzigd door Twazerty op 26-12-2008 19:32 ]

Ruisende versterker: schakel je subwoofer in.


Acties:
  • 0 Henk 'm!

  • djexplo
  • Registratie: Oktober 2000
  • Laatst online: 07-07 15:40
"taskkill /im cmd.exe /f" als shell command uitvoeren

'if it looks like a duck, walks like a duck and quacks like a duck it's probably a duck'


Acties:
  • 0 Henk 'm!

  • krvabo
  • Registratie: Januari 2003
  • Laatst online: 09:51

krvabo

MATERIALISE!

Even googlen kwam met:
Java:
1
2
3
4
5
Process p = Runtime.exec("ls");
.....
if (...) {
p.destroy();
}

Als dat niet doet wat je wil, kun je ook nog Runtime.exit() gebruiken. Mocht dat niet werken dan kun je de code gebruiken die je zelf aangeeft (met de hook) om daarna alsnog exit() te gebruiken.
Mocht dat ook niet lukken dann heb je alsnog als uiterlijke mogelijkheid Runtime.halt(), maar dat kun je maar beter niet gebruiken.

Een voorbeeld: http://www.esus.com/javai...2/javalang/trapctrlc.html

[ Voor 8% gewijzigd door krvabo op 26-12-2008 19:44 ]

Pong is probably the best designed shooter in the world.
It's the only one that is made so that if you camp, you die.


Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
Kom er niet echt uit en exit doet niet wat ik wil. Dit is mijn java code om te schrijven naar cmd.exe:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class CmdExecuter {

    BufferedWriter writer;
    
    public CmdExecuter(String arg, int mode){
        try
        {            
            String osName = System.getProperty("os.name" );
            String[] cmd = new String[1];
            
            cmd[0] = "cmd.exe" ;
            
            Runtime rt = Runtime.getRuntime();
            System.out.println("Execing " + cmd[0]);
            Process proc = rt.exec(cmd);
            // any error message?
            Stream errorGobbler = new Stream(proc.getErrorStream(), "ERROR", mode);
            
            // any output?
            //de streamreader om tevens het resultaat weer te geven in de console. Draait in eigen Thread.
            Stream outputGobbler = new Stream(proc.getInputStream(), "OUTPUT", mode); 

                
            // kick them off
            errorGobbler.start();
            outputGobbler.start();
            
            OutputStreamWriter osw = new OutputStreamWriter(proc.getOutputStream());
            writer = new BufferedWriter(osw);
            
            writer(writer, arg);
            // any error???
            int exitVal = proc.waitFor();
            System.out.println("ExitValue: " + exitVal);        
        } catch (Throwable t){
            t.printStackTrace();
        }
    }
    
    public void writer(BufferedWriter writer, String arg){ 
        try {
            writer.write(arg + "\n"); //word uitgevoerd
            writer.write("exit\n");//word pas uitgevoerd als vorige regel klaar is.
            writer.flush();
            
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

een argument wat geschreven kan worden is bijvoorbeeld:
"C:\DTS To AC3\bepipe.exe" --script "import(^DTS.avs^)" - | "C:\DTS To AC3\aften.exe" -v 0 -b 448 -dynrng 5 - "C:\output.ac3"
dit word dus geschreven in cmd.exe en is dus een extern process. Dit extern process wil ik dus kunnen stoppen. Dus hetzelfde effect als Ctrl-C in de normale cmd console. Alleen dan anders. Want ik heb het idee alsof de gegeven info over net iets anders gaat. Deze klasse word aangeroepen van hogerop. Dat draait wel weer in een eigen Thread als losstaande Thread van de rest van het programma. Nu wil ik dus een knopje Cancel toevoegen zodat het gehele process (encoderen) gestopt word. Dus ook de externe processen die aangeroepen zijn.

@djexplo, daar heb ik volgens mij niks aan. Dat word ook pas uitgevoerd als het externe programma. In dit geval dus bePipe klaar is.

@krvabo, ik heb dus geen idee waar ik dat moet implementeren. Weet ook niet of het wel hetgene is wat ik zoek.

Ruisende versterker: schakel je subwoofer in.


Acties:
  • 0 Henk 'm!

Verwijderd

Je hebt cmd.exe toch helemaal niet nodig? Je kan direct Runtime.exec() gebruiken voor het te draaien proces. Dat is ook direct cross-platform.

Of is die pipe een onderdeel van cmd? In dat geval natuurlijk wel, maar dan kan je toch alsnog het proces killen met destroy()?

[ Voor 44% gewijzigd door Verwijderd op 26-12-2008 21:35 ]


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Verwijderd schreef op vrijdag 26 december 2008 @ 21:20:
Je hebt cmd.exe toch helemaal niet nodig? Je kan direct Runtime.exec() gebruiken voor het te draaien proces. Dat is ook direct cross-platform.

Of is die pipe een onderdeel van cmd? In dat geval natuurlijk wel, maar dan kan je toch alsnog het proces killen met destroy()?
Pipe heb je ook in Linux' textmode / CLI. cmd.exe dan weer niet, of je moet het draaien binnen WINE, als je dan überhaupt CMD hebt... ;)

[ Voor 6% gewijzigd door CH4OS op 26-12-2008 21:45 ]


Acties:
  • 0 Henk 'm!

  • kw4h
  • Registratie: Februari 2008
  • Laatst online: 22-09 09:00
Twazerty schreef op vrijdag 26 december 2008 @ 20:41:
Java:
1
Process proc = rt.exec(cmd);
Als je zorgt dat dit object ('proc') van buiten je thread beschikbaar is, kan je het proces op elk gewenst moment killen door 'proc.destroy()' uit te voeren.
Zie: http://java.sun.com/javase/6/docs/api/java/lang/Process.html

Als het goed is heeft dit hetzelfde effect als Ctrl+C (aangezien dit een soort van kill signaal doorgeeft aan het proces).

Acties:
  • 0 Henk 'm!

Verwijderd

GJtje schreef op vrijdag 26 december 2008 @ 21:44:
[...]
Pipe heb je ook in Linux' textmode / CLI. cmd.exe dan weer niet, of je moet het draaien binnen WINE, als je dan überhaupt CMD hebt... ;)
Het zou natuurlijk helemaal mooi zijn als Java ook een pipe zou ondersteunen bij het runnen van commands. Volgens mij heeft Java echter geen shell aan boord, en abstraheert het die ook niet. Je zult dus zelf cmd.exe of bash moeten starten.

Op zich abstraheert Java natuurlijk wel een pipe: je kan de outputstream van het ene proces aan de inputstream van het andere proces koppelen door van het ene naar het andere te write()en. Alleen is een simpele "|" natuurlijk wel iets makkelijker.

Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
Volgens mij gaat het niet via exec. Externe windows programma's gaan ook meedraaien zoals ffdshow en mkvsplitter. Ga tevens x264.exe, tsmuxer, mkvmerge, mkvsplit, mkvinfo gebruiken. Dus laat ik het maar bij windows houden :)
Via cmd draait alles nu en om nu weer alles te verbouwen :)

proc.destroy() levert mij een exception op en het process draait gewoon door. Zowel bepipe.exe als de output die het genereerd in de console. In het begin van de flow de GUI dus heb ik een Process proc variable bijgevoegd. En geef proc gewoon telkens mee aan de volgende klasse/methode. Om uiteindelijk bij bovenstaande code proc = rt.exec(cmd); uit te voeren. Dan lijkt het me dat dat gewoon moet werken. Ik zie denk ik iets over het hoofd. Dit is de exception:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
dit gebeurt als ik in de GUI proc.destroy() aanroep.

Edit: Java beginner (2e jaar Informatica HBO) dus laten we het niet al te moeilijk maken. Om cmd aan te sturen was ik al effe mee bezig. :) Dit is verder gewoon een hobby project. MKV to AVCHD. All In One

[ Voor 10% gewijzigd door Twazerty op 26-12-2008 23:15 ]

Ruisende versterker: schakel je subwoofer in.


Acties:
  • 0 Henk 'm!

Verwijderd

Twazerty schreef op vrijdag 26 december 2008 @ 23:08:
Volgens mij gaat het niet via exec. Externe windows programma's gaan ook meedraaien zoals ffdshow en mkvsplitter. Ga tevens x264.exe, tsmuxer, mkvmerge, mkvsplit, mkvinfo gebruiken. Dus laat ik het maar bij windows houden :)
Al die programma's zijn cross-platform, en de pipe-functionaliteit is hetzelfde in cmd.exe en bash, dus dat is geen probleem.

Ik vind het altijd maar erg lastig te zien met events, maar een Nullpointer-exception zou ik bij proc.destroy() alleen verwachten als 'proc' null is. Blijkbaar heeft proc dus geen object aan zich hangen in die thread. In die richting moet je 't denk ik zoeken.

Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
daar zat ik ook aan te denken. Helemaal onderaan de tree word process pas werkelijk ingevuld. Namelijk door rt.exec(cmd);. Normaal gesproken zou ik dan helemaal bovenaan de tree gewoon een methode aan moeten kunnen roepen aangezien het object proc alleen maaar een referentie bevat. Lijkt erop dat dat niet zo is. Normaal heb je bovenaan dan ergens iets van new. Nu gebeurt zoiets pas helemaal onderaan. Zou dat het probleem kunnen zijn? Kan het een Thread probleem zijn? aangezien de GUI los draait van de Jobs die gedaan moeten worden.

Edit:
Heb dit nu verplaatst naar de GUI:
Java:
1
2
3
4
5
6
7
8
String osName = System.getProperty("os.name" ); 
            String[] cmd = new String[1]; 
             
            cmd[0] = "cmd.exe" ; 
             
            Runtime rt = Runtime.getRuntime(); 
            System.out.println("Execing " + cmd[0]); 
            proc = rt.exec(cmd); 


Zodat ik destroy vanuit de GUI aan kan roepen. Het bijna. In ieder geval geen exceptions. maar het process blijft gewoon lopen. Ook de output van cmd blijft gewoon doorlopen.

[ Voor 33% gewijzigd door Twazerty op 27-12-2008 00:05 ]

Ruisende versterker: schakel je subwoofer in.


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Heeft DOS niet zoiets als een "kill pid" of "killall procesnaam" of e.o.a. andere mechanisme waarmee je een sigterm/sigint kan sturen naar die running process? Weet niet in hoeverre "dos/windows" echt posix compliant is namelijk.

Acties:
  • 0 Henk 'm!

Verwijderd

code:
1
taskkill /F /IM cmd.exe

Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
is al eerder gepost zie ik. Heb het even geprobeerd via een nieuwe streamwriter. Cmd.exe word mooi gekilled. Maar niet de bijbehorende processen. Deze blijven gewoon doordraaien inclusief de output die terugkomt van de commandline. Denk dat er niks anders opzit als handmatig de overige processen te killen. Alleen dan ipv taskkill /F /IM cmd.exe doe ik dan taskkill /F /IM bepipe.exe enz. Ik weet toch welke processen er extern draaien. Dus dat is opzich geen probleem. Wellicht nog een andere oplossing die werkt?

Ruisende versterker: schakel je subwoofer in.


Acties:
  • 0 Henk 'm!

Verwijderd

/t parameter: Specifies to terminate all child processes along with the parent process, commonly known as a tree kill.

code:
1
taskkill /F /IM /t cmd.exe


Misschien dat dit wel werkt?

Acties:
  • 0 Henk 'm!

  • Twazerty
  • Registratie: April 2006
  • Laatst online: 10:37

Twazerty

AVCHDCoder developer

Topicstarter
Verwijderd schreef op zondag 28 december 2008 @ 13:09:
/t parameter: Specifies to terminate all child processes along with the parent process, commonly known as a tree kill.

code:
1
taskkill /F /IM /t cmd.exe


Misschien dat dit wel werkt?
Jep het werkt. Jippie. /t moest wel voor /IM staan :P

[ Voor 10% gewijzigd door Twazerty op 28-12-2008 16:01 ]

Ruisende versterker: schakel je subwoofer in.

Pagina: 1