me.at.coding
me.at.coding

Reputation: 17604

Interacting with a command line process

I need to interact with a command line process, e.g. diskpart on windows. The problem: input.readLine() in the following sample leads to a blocking while.

public static void main(String[] args) throws IOException 
{
    ProcessBuilder processBuilder = new ProcessBuilder("C:\\Windows\\system32\\diskpart.exe");                      
    processBuilder.redirectErrorStream(true);
    Process process = processBuilder.start();

    input = new BufferedReader(new InputStreamReader(process.getInputStream()));
    output = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

    // read #1 code position
    String line = null;
    while((line = input.readLine())!= null)
        System.out.println(line);

    // code position #2
    System.out.println("This line is never executed");   

    output.write("list disk" + System.lineSeparator());
    output.flush(); // important
}

The output (from read #1 code position) is

Microsoft DiskPart-Version 6.1.7601
Copyright (C) 1999-2008 Microsoft Corporation.
Auf Computer: MYPC

This is correct, however after that nothing happens, e.g. code position #2

System.out.println("This line is never executed"); 

is never reached. Can anyone tell me, why and how to fix this? Thanks!

Update:

Trying to read byte by byte also seems not to work? ):

    InputStreamReader input = new InputStreamReader(process.getInputStream());
    int mychar = -1;

    while((mychar = input.read()) != -1)
        System.out.println(mychar);

    System.out.println("This line is never executed"); 

Upvotes: 0

Views: 3198

Answers (2)

Reimeus
Reimeus

Reputation: 159754

Diskpart has an interactive console that requires input from the user. Attempting to read its output like this:

while((line = input.readLine())!= null)
      System.out.println(line);

will cause you to wait indefinitely as the application itself requires input.

You need to wait for input first from the windows command so you need to add CMD /C to your command.

As diskpart is interactive, you could try running your list command as a script, so you would have instead:

String[] command = {"CMD", "/C", "C:\\Windows\\system32\\diskpart.exe", "/s", "diskpart.txt"};
ProcessBuilder processBuilder = new ProcessBuilder(command); 

with diskpart.txt containing:

list disk

I recommend you getting this working in a standard batch file first though to check that the output is correct.

Upvotes: 1

user9876
user9876

Reputation: 11102

Because the next thing Diskpart does is show the prompt, which doesn't include a newline:

Microsoft DiskPart version 6.1.7601
Copyright (C) 1999-2008 Microsoft Corporation.
On computer: PCNAME

DISKPART> _

So your code sits there waiting for the newline, which never appears.

You need to change your code to send the "list disk" command at the right time.

Upvotes: 3

Related Questions