我正在尝试创建一个让netsh windows命令行工具保持打开状态的Thread,这样我就可以执行netsh命令而不必每次都打开它。
问题是,一旦我创建了Thread,只需要第一个命令调用......后续调用似乎没有效果。
这是我的代码:
public class NetshThread implements Runnable{
private static Process netshProcess = null;
private static BufferedInputStream netshInStream = null;
private static BufferedOutputStream netshOutStream = null;
public BufferedReader inPipe = null;
public void run(){
startNetsh();
}
public void startNetsh(){
try {
netshProcess = Runtime.getRuntime().exec("netsh");
netshInStream = new BufferedInputStream(netshProcess.getInputStream());
netshOutStream = new BufferedOutputStream(netshProcess.getOutputStream());
inPipe = new BufferedReader(new InputStreamReader(netshInStream));
} catch (IOException e) {
e.printStackTrace();
}
}
public void executeCommand(String command){
System.out.println("Executing: " + command);
try {
String str = "";
netshOutStream.write(command.getBytes());
netshOutStream.close();
while ((str = inPipe.readLine()) != null) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void closeNetsh(){
executeCommand("exit");
}
public static void main(String[] args){
NetshThread nthread = new NetshThread();
nthread.run();
String command = "int ip set address " +
"\"Local Area Connection 6\" static .69.69.69 255.255.255.0";
nthread.executeCommand(command);
command = "int ip set address " +
"\"Local Area Connection 6\" static 69.69.69.69 255.255.255.0";
nthread.executeCommand(command);
System.out.println("*** DONE ***");
}
}
谢谢!!! =)
好的......我现在正在使用PrintWriter ...所以我认为我不需要再刷新任何东西了,因为构造函数是:
new PrintWriter(netshOutStream,true); (就像Shiny先生告诉我的那样)......
假设我决定在第一个输出行可用时断开while循环...我也不工作......下一个命令不会被执行....我的代码现在看起来像:
import java.io.*;
public class NetshThread implements Runnable{
private static Process netshProcess = null;
private static BufferedInputStream netshInStream = null;
private static BufferedOutputStream netshOutStream = null;
public BufferedReader inPipe = null;
private PrintWriter netshWriter = null;
public void run(){
startNetsh();
}
public void startNetsh(){
try {
netshProcess = Runtime.getRuntime().exec("netsh");
netshInStream = new BufferedInputStream(netshProcess.getInputStream());
netshOutStream = new BufferedOutputStream(netshProcess.getOutputStream());
netshWriter = new PrintWriter(netshOutStream, true);
inPipe = new BufferedReader(new InputStreamReader(netshInStream));
} catch (IOException e) {
e.printStackTrace();
}
}
public void executeCommand(String command){
System.out.println("Executing: " + command);
try {
String str = "";
netshWriter.println(command);
while ((str = inPipe.readLine()) != null) {
System.out.println(str);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void closeNetsh(){
executeCommand("exit");
}
public static void main(String[] args){
NetshThread nthread = new NetshThread();
Thread xs = new Thread(nthread);
xs.run();
String command = "int ip set address " +
"\"Local Area Connection 6\" static .69.69.69 255.255.255.0";
nthread.executeCommand(command);
command = "int ip set address " +
"\"Local Area Connection 6\" static 69.69.69.69 255.255.255.0";
nthread.executeCommand(command);
System.out.println("*** DONE ***");
}
}
和我得到的输出:
执行:int ip set address“Local 区域连接6“静态.69.69.69 对于addr,255.255.255.0 netsh> .69.69.69不是可接受的值。 执行:int ip set address“Local 区域连接6“静态69.69.69.69
为什么不执行第二个命令???
255.255.255.0
*完成*
在教师在西班牙语窗口环境中尝试我的应用程序之前,一切似乎都运行良好....
我的代码如下:
Scanner fi = new Scanner(netshProcess.getInputStream());
public void executeCommand(String command) {
System.out.println("Executing: " + command);
String str = "";
netshWriter.println(command);
fi.skip("\\s*");
str = fi.nextLine();
System.out.println(str);
}
我需要的是以某种方式将netshWriter编码设置为Windows默认值。
谁能知道该怎么做?
答案 0 :(得分:3)
您正在关闭输出流。
答案 1 :(得分:2)
您需要将流处理移动到单独的线程中。发生的事情是 inPipe.readLine()阻止等待netsh返回数据。 Apache有一个处理进程处理的包。我会考虑使用它而不是滚动你自己的(http://commons.apache.org/exec/)
答案 2 :(得分:1)
这在很多方面都是错误的。
首先,为什么一个Runnable对象?这在任何地方都没有传递给Thread。您创建的唯一线程不是java线程,它是由exec()创建的OS进程。
其次,您需要一种方法来了解何时完成netsh。读取netsh输出的循环将永远运行,因为当netsh关闭其标准输出时,readLine将仅返回null(在您的情况下永远不会)。在处理完请求时,您需要查找netsh打印的标准内容。
正如其他人所说,关闭是坏事。使用同花顺。希望netsh使用同花顺回复你......
答案 3 :(得分:0)
您确实需要删除close
,否则您永远无法执行其他命令。当删除close()调用后说“它将无法工作”时,是否意味着没有命令被处理?
有可能在您发送命令的字节后,您需要发送某种确认密钥以启动进程,然后处理它。如果你通常从键盘输入它,它可能就像回车一样简单,否则它可能需要是Ctrl-D或类似的。
我尝试用
替换close()行netshOutStream.write('\n');
看看是否有效。根据软件的不同,您可能需要更改发送的字符以表示命令的结束,但这种一般方法应该可以帮助您完成。
编辑:
调用
也是明智的netshOutStream.flush();
以上几行之后;如果没有刷新,则无法保证您的数据将被写入,实际上,因为您正在使用BufferedInputStream,我99%确定在刷新流之前不会写入任何 。因此,为什么后面的代码会阻塞,因为你正在等待响应,而进程还没有看到任何输入,并且正在等待你发送一些。
答案 4 :(得分:0)
我试试:
PrintWriter netshWriter = new PrintWriter(netshOutputStream, true); // auto-flush writer
netshWriter.println(command);
没有关闭()流,自动刷新流,并使用编写器发送字符数据,而不是依赖平台“本机字符集”。
答案 5 :(得分:0)
我使用的是扫描仪而不是BufferedReader,因为我喜欢它。所以这段代码有效:
Scanner fi = new Scanner(netshProcess.getInputStream());
public void executeCommand(String command) {
System.out.println("Executing: " + command);
String str = "";
netshWriter.println(command);
fi.skip("\\s*");
str = fi.nextLine();
System.out.println(str);
}
它执行两个命令。