本文介绍了Java ProcessBuilder 进程等待输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当通过 ProcessBuilder(特别是GetMac/s")运行命令行命令时,如果它抛出错误或正常返回,我可以读取错误或它返回的 MAC 地址,但如果它提示用户输入(某些电脑的在网络上使用 getmac 时需要密码)该进程将挂起等待密码.

When running a command line command via ProcessBuilder (specifically "GetMac /s") if it throws an error or returns normally and I can read the error or the MAC address that it returns but if it prompts the user input (some pc's on the network require a password when using getmac) the process will just hang waiting for the password.

这是从命令行运行时命令的作用:

Here is what the command does when run from command line:

这是我用于该过程的代码:

Here is the code I'm using for the process:

package testing;
import java.io.IOException;

class test1 {
    public static void main(String[] args){
        String hostName = "testpc";
        ProcessBuilder builder = new ProcessBuilder("getmac", "/s", hostName, "/nh");
        builder.inheritIO();
        try {
            Process proc = builder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我需要 mac 的原因是为了在 lan 程序上进行唤醒,并希望在检测到任何新电脑的 mac 地址时自动获取它们,这样用户就不必手动输入.所以如果你知道一种更好的方法来获取远程电脑的 MAC,请告诉我,我会改用它.

The reason I need the mac is for making a wake on lan program and want to automatically get any new pc's mac addresses when they're detected so the user doesn't have to enter it manually. so if you know a better way of getting the MAC of a remote pc by all means let me know and I'll use that instead.

我意识到 Java 可能不是用于此的最佳语言,但它是我目前唯一知道的一种语言,这只是我在工作中的停机时间的一个有趣的小项目.

I realize java probably isn't the best language to be using for this but it's the only one I know at the moment and this is just fun little project for my downtime at work.

**如果它需要密码,我只想忽略那台 PC 并终止进程并转到下一台 PC

** if it requries a password I just want to ignore that PC and kill the process and move on to the next PC

推荐答案

您需要处理与 Process 关联的所有 Streams,包括 InputStream、ErrorStream 和 OutputStream.您在命令行上看到的文本将通过 InputStream 传入,然后您需要通过 OutputStream 传递请求的信息.

You need to handle all the Streams associated with the Process, including the InputStream, ErrorStream and OutputStream. The text you see on the command line will be coming through the InputStream, and you'll then want to pass information requested through the OutputStream.

您需要在它们自己的线程中读取 InputStream 和 ErrorStream.如果它们传递文本,我经常将它们包装在 Scanner 对象中,我经常将 OutputStream 包装在 BufferedOutputStream 中,并将其包装在 PrintStream 对象中.

You'll want to read the InputStream and the ErrorStream both in their own Threads. I often wrap them in a Scanner object if they're passing text, and I often wrap the OutputStream in a BufferedOutputStream, and that in a PrintStream object.

例如

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Scanner;

class Test1 {
   private static PrintStream out;

   public static void main(String[] args) {
      String hostName = "testpc";
      String[] commands = {"getmac", "/s", hostName,
            "/nh"};
      ProcessBuilder builder = new ProcessBuilder(commands);

      // builder.inheritIO(); // I avoid this. It was messing me up.

      try {
         Process proc = builder.start();
         InputStream errStream = proc.getErrorStream();
         InputStream inStream = proc.getInputStream();
         OutputStream outStream = proc.getOutputStream();

         new Thread(new StreamGobbler("in", out, inStream)).start();
         new Thread(new StreamGobbler("err", out, errStream)).start();

         out = new PrintStream(new BufferedOutputStream(outStream));
         int errorCode = proc.waitFor();
         System.out.println("error code: " + errorCode);
      } catch (IOException e) {
         e.printStackTrace();
      } catch (InterruptedException e) {
         e.printStackTrace();
      } finally {
         if (out != null) {
            out.close();
         }
      }
   }
}

class StreamGobbler implements Runnable {
   private PrintStream out;
   private Scanner inScanner;
   private String name;

   public StreamGobbler(String name, PrintStream out, InputStream inStream) {
      this.name = name;
      this.out = out;
      inScanner = new Scanner(new BufferedInputStream(inStream));
   }

   @Override
   public void run() {
      while (inScanner.hasNextLine()) {
         String line = inScanner.nextLine();

         // do something with the line!
         // check if requesting password

         System.out.printf("%s: %s%n", name, line);
      }
   }
}

这篇关于Java ProcessBuilder 进程等待输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 04:07